{"record":{"id":"30f34eb4ff6baee8","repo":"charmbracelet/crush","slug":"failed-to-remove-config-field-w","errorCode":null,"errorMessage":"failed to remove config field: %w","messagePattern":"failed to remove config field: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/config.go","lineNumber":38,"sourceCode":"\t}{Scope: scope, Key: key, Value: value}), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to set config field: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to set config field: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// RemoveConfigField removes a config key on the server.\nfunc (c *Client) RemoveConfigField(ctx context.Context, id string, scope config.Scope, key string) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/config/remove\", id), nil, jsonBody(struct {\n\t\tScope config.Scope `json:\"scope\"`\n\t\tKey   string       `json:\"key\"`\n\t}{Scope: scope, Key: key}), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to remove config field: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to remove config field: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// UpdatePreferredModel updates the preferred model on the server.\nfunc (c *Client) UpdatePreferredModel(ctx context.Context, id string, scope config.Scope, modelType config.SelectedModelType, model config.SelectedModel) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/config/model\", id), nil, jsonBody(struct {\n\t\tScope     config.Scope             `json:\"scope\"`\n\t\tModelType config.SelectedModelType `json:\"model_type\"`\n\t\tModel     config.SelectedModel     `json:\"model\"`\n\t}{Scope: scope, ModelType: modelType, Model: model}), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to update preferred model: %w\", err)\n\t}","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/config.go#L20-L56","documentation":"RemoveConfigField wraps a transport-level failure of the POST to /workspaces/{id}/config/remove. The removal request never completed.","triggerScenarios":"c.post returns an error (connection failure, canceled context) when removing a config key; called by logoutHyper and logoutCopilot.","commonSituations":"During logout flows the server has already exited, so the connection fails; socket/port stale after a crash.","solutions":["During logout, treat this as non-fatal if the key will be cleared anyway","Verify server connectivity and retry the removal","Check the wrapped error to distinguish connection refused from other causes"],"exampleFix":"// before\nif err := c.RemoveConfigField(ctx, id, scope, key); err != nil {\n    return err\n}\n// after\nif err := c.RemoveConfigField(ctx, id, scope, key); err != nil {\n    log.Warn(\"failed to remove config field during logout\", \"err\", err)\n    // continue logout; do not block on cleanup\n}","handlingStrategy":"fallback","validationCode":"// During logout, check server liveness first\nif _, err := os.Stat(socketPath); err != nil {\n    return nil // server gone; nothing to remove\n}","typeGuard":null,"tryCatchPattern":"if err := c.RemoveConfigField(ctx, id, scope, key); err != nil {\n    log.Warn(\"config removal failed, continuing logout\", \"err\", err)\n}","preventionTips":["Make logout cleanup non-fatal","Check server liveness before removal calls","Ignore failures for keys that will not be read again"],"tags":["http","network","config","logout"],"backgroundTag":"http-request-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}