charmbracelet/crush · error

failed to remove config field: status code %d

Error message

failed to remove config field: status code %d

What it means

RemoveConfigField's server-rejection path: the server answered with a non-200 status. No sentinel wrapping is applied; the status code is embedded in the message.

Source

Thrown at internal/client/config.go:42

	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to set config field: status code %d", rsp.StatusCode)
	}
	return nil
}

// RemoveConfigField removes a config key on the server.
func (c *Client) RemoveConfigField(ctx context.Context, id string, scope config.Scope, key string) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/config/remove", id), nil, jsonBody(struct {
		Scope config.Scope `json:"scope"`
		Key   string       `json:"key"`
	}{Scope: scope, Key: key}), http.Header{"Content-Type": []string{"application/json"}})
	if err != nil {
		return fmt.Errorf("failed to remove config field: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to remove config field: status code %d", rsp.StatusCode)
	}
	return nil
}

// UpdatePreferredModel updates the preferred model on the server.
func (c *Client) UpdatePreferredModel(ctx context.Context, id string, scope config.Scope, modelType config.SelectedModelType, model config.SelectedModel) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/config/model", id), nil, jsonBody(struct {
		Scope     config.Scope             `json:"scope"`
		ModelType config.SelectedModelType `json:"model_type"`
		Model     config.SelectedModel     `json:"model"`
	}{Scope: scope, ModelType: modelType, Model: model}), http.Header{"Content-Type": []string{"application/json"}})
	if err != nil {
		return fmt.Errorf("failed to update preferred model: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to update preferred model: status code %d", rsp.StatusCode)
	}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check the status code in the message to decide whether removal matters
  2. Ignore non-200 during logout cleanup when the key is irrelevant afterward
  3. Ensure the workspace is alive before attempting config mutation
Defensive patterns

Strategy: fallback

Validate before calling

// Skip the call when the workspace is known to be gone
if !workspaceExists(id) {
    return nil
}

Try / catch

if err := c.RemoveConfigField(ctx, id, scope, key); err != nil {
    if strings.Contains(err.Error(), "status code 404") {
        return nil // already gone
    }
    return err
}

Prevention

When it happens

Trigger: POST /workspaces/{id}/config/remove returns non-200, e.g. 404 unknown workspace or 400 malformed key.

Common situations: Logging out of Hyper/Copilot after the workspace was already deleted; removing a key the server never stored.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/99357956ee66a826. Report an issue: GitHub.