charmbracelet/crush · error
failed to delete workspace: status code %d
Error message
failed to delete workspace: status code %d
What it means
DeleteWorkspace requires an exact HTTP 200; any other status (e.g. 403, 404, 409, 500) produces this error with the status code embedded. Unlike checkStatus-based paths this branch reports only the numeric code, so the server's error detail body is not included. It means the server actively rejected or failed the delete.
Source
Thrown at internal/client/proto.go:84
return nil, fmt.Errorf("failed to get workspace: %w", err)
}
var ws proto.Workspace
if err := json.NewDecoder(rsp.Body).Decode(&ws); err != nil {
return nil, fmt.Errorf("failed to decode workspace: %w", err)
}
return &ws, nil
}
// DeleteWorkspace deletes a workspace on the server.
func (c *Client) DeleteWorkspace(ctx context.Context, id string) error {
q := url.Values{"client_id": []string{c.clientID}}
rsp, err := c.delete(ctx, fmt.Sprintf("/workspaces/%s", id), q, nil)
if err != nil {
return fmt.Errorf("failed to delete workspace: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to delete workspace: status code %d", rsp.StatusCode)
}
return nil
}
// SetCurrentSession reports the client's current-session selection
// for the named workspace. An empty sessionID clears the entry. The
// request carries the process-scoped client ID minted in [NewClient]
// as a query parameter so the server can route the update to the
// correct [clientState] entry.
func (c *Client) SetCurrentSession(ctx context.Context, workspaceID, sessionID string) error {
q := url.Values{"client_id": []string{c.clientID}}
rsp, err := c.post(
ctx,
fmt.Sprintf("/workspaces/%s/current-session", workspaceID),
q,
jsonBody(proto.CurrentSession{SessionID: sessionID}),
http.Header{"Content-Type": []string{"application/json"}},
)View on GitHub (pinned to 7944b8e522)
Solutions
- Treat 404 as success (workspace already gone) and ignore it.
- Re-list workspaces (ListWorkspaces) to refresh ids before deleting.
- If ownership errors occur, create the workspace with the current client (CreateWorkspace stamps ws.ClientID) or restart from a fresh list.
- Check server logs for the status code to find the 5xx cause.
Example fix
// before
if err := client.DeleteWorkspace(ctx, id); err != nil { return err }
// after: tolerate already-deleted
if err := client.DeleteWorkspace(ctx, id); err != nil {
if strings.Contains(err.Error(), "status code 404") {
return nil
}
return err
} Defensive patterns
Strategy: validation
Validate before calling
// verify existence and ownership before deleting
wss, err := client.ListWorkspaces(ctx)
if err != nil { return err }
owned := false
for _, w := range wss {
if w.ID == id && w.ClientID == myClientID { owned = true }
}
if !owned { return fmt.Errorf("workspace %q not owned by this client", id) } Try / catch
err := client.DeleteWorkspace(ctx, id)
var statusErr interface{ StatusCode() int }
switch {
case err == nil:
return nil
case strings.Contains(err.Error(), "status code 404"):
return nil // already gone
default:
return err
} Prevention
- Refresh the workspace list before deleting.
- Remember client IDs are process-scoped and change on restart.
- Treat 404 as success in cleanup paths.
- Match on the embedded status code, not the generic message.
When it happens
Trigger: Calling client.DeleteWorkspace(ctx, id) when the workspace does not exist (404), the client_id does not own the workspace (403/409), or the server errors while removing state (5xx).
Common situations: Deleting an already-deleted workspace from another client session; ownership mismatch because the client was restarted and minted a new client ID (NewClient generates a process-scoped ID); stale workspace list from before a server restart.
Related errors
- failed to refresh OAuth token: status code %d
- failed to check project init: status code %d
- failed to mark project initialized: status code %d
- failed to get init prompt: status code %d
- failed to list skills: status code %d
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/cde074c65014eeef.
Report an issue: GitHub.