{"record":{"id":"10008da130d41b4f","repo":"charmbracelet/crush","slug":"failed-to-create-workspace-w","errorCode":null,"errorMessage":"failed to create workspace: %w","messagePattern":"failed to create workspace: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":45,"sourceCode":"\t\treturn nil, fmt.Errorf(\"failed to list workspaces: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to list workspaces: status code %d\", rsp.StatusCode)\n\t}\n\tvar workspaces []proto.Workspace\n\tif err := json.NewDecoder(rsp.Body).Decode(&workspaces); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode workspaces: %w\", err)\n\t}\n\treturn workspaces, nil\n}\n\n// CreateWorkspace creates a new workspace on the server.\nfunc (c *Client) CreateWorkspace(ctx context.Context, ws proto.Workspace) (*proto.Workspace, error) {\n\tws.ClientID = c.clientID\n\trsp, err := c.post(ctx, \"/workspaces\", nil, jsonBody(ws), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create workspace: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif err := checkStatus(rsp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create workspace: %w\", err)\n\t}\n\tvar created proto.Workspace\n\tif err := json.NewDecoder(rsp.Body).Decode(&created); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode workspace: %w\", err)\n\t}\n\treturn &created, nil\n}\n\n// GetWorkspace retrieves a workspace from the server.\nfunc (c *Client) GetWorkspace(ctx context.Context, id string) (*proto.Workspace, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s\", id), nil, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get workspace: %w\", err)\n\t}","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L27-L63","documentation":"CreateWorkspace wraps a failure of the underlying POST request (transport error) with \"failed to create workspace\". This occurs before a response exists — connection, DNS, timeout, or context cancellation problems while POSTing to /workspaces.","triggerScenarios":"Calling CreateWorkspace (via createWorkspaceOnLiveServer) when the HTTP POST cannot be completed: daemon not running, connection refused/reset, request deadline exceeded, or context canceled.","commonSituations":"Server crashed between a health check and the create call; network interruption; overly tight context timeout during startup; wrong address/port configuration.","solutions":["Check the wrapped error for connection refusal — start or restart the daemon.","Verify the configured server address and port.","Increase the context timeout if creation happens during slow startup.","Check server logs and connectivity (firewall, proxy) between client and daemon."],"exampleFix":"// before\ncreated, err := client.CreateWorkspace(ctx, ws)\nif err != nil {\n\treturn err\n}\n// after: retry transient transport failures with backoff\ncreated, err := client.CreateWorkspace(ctx, ws)\nif err != nil && isTransientNetErr(err) {\n\tctx2, cancel := context.WithTimeout(ctx, 10*time.Second)\n\tdefer cancel()\n\tcreated, err = client.CreateWorkspace(ctx2, ws)\n}\nif err != nil {\n\treturn err\n}","handlingStrategy":"retry","validationCode":"// Confirm the daemon accepts connections before creating\nconn, err := net.DialTimeout(\"tcp\", serverAddr, 2*time.Second)\nif err != nil {\n\treturn fmt.Errorf(\"daemon not running at %s\", serverAddr)\n}\nconn.Close()\n// Validate payload before sending\nif ws.Path == \"\" {\n\treturn errors.New(\"workspace path is required\")\n}","typeGuard":"func isTransportFailure(err error) bool {\n\treturn err != nil && !strings.Contains(err.Error(), \"status code\")\n}","tryCatchPattern":"created, err := client.CreateWorkspace(ctx, ws)\nif err != nil {\n\tvar netErr net.Error\n\tif errors.As(err, &netErr) {\n\t\treturn retryWithBackoff(ctx, 3, func() error {\n\t\t\tcreated, err = client.CreateWorkspace(ctx, ws)\n\t\t\treturn err\n\t\t})\n\t}\n\treturn err\n}","preventionTips":["Health-check the daemon immediately before write operations.","Use bounded retries with backoff for transient network failures.","Set realistic context deadlines for workspace creation during startup.","Fail fast with a clear message when the daemon is simply not running."],"tags":["network","http","client","workspaces"],"backgroundTag":"connection-refused","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}