charmbracelet/crush · error
failed to create workspace: %v
Error message
failed to create workspace: %v
What it means
createWorkspaceOnLiveServer in internal/cmd/root.go retries client.CreateWorkspace up to maxStaleServerRetries when the server reports it is shutting down (client.ErrServerShuttingDown). Any non-shutdown error, or exhausting the final retry, returns 'failed to create workspace: %v' wrapping the underlying cause.
Source
Thrown at internal/cmd/root.go:473
// createWorkspaceOnLiveServer creates the workspace, retrying against a
// replacement when the server it reached has already committed to shutting
// itself down for being idle.
//
// That race is unavoidable: the server decides to exit while no client is
// talking to it, and a client can arrive between that decision and the
// socket going away. The decision is final on the server's side, so the
// only correct response is to bring up a fresh server and ask again
// instead of failing the command.
func createWorkspaceOnLiveServer(
ctx context.Context, c *client.Client, req proto.Workspace, replace func() error,
) (*proto.Workspace, error) {
for attempt := range maxStaleServerRetries {
ws, err := c.CreateWorkspace(ctx, req)
if err == nil {
return ws, nil
}
if !errors.Is(err, client.ErrServerShuttingDown) || attempt == maxStaleServerRetries-1 {
return nil, fmt.Errorf("failed to create workspace: %v", err)
}
slog.Warn("Server is shutting down; retrying against a replacement",
"attempt", attempt+1, "error", err)
if err := replace(); err != nil {
return nil, err
}
}
return nil, fmt.Errorf("failed to create workspace: server kept shutting down")
}
// replaceExitingServer waits out the socket of a server that has committed
// to exiting, then brings up a fresh one.
func replaceExitingServer(cmd *cobra.Command, hostURL *url.URL) error {
if hostURL.Scheme == "unix" {
if err := awaitSocketGone(cmd.Context(), hostURL); err != nil {
return err
}
}View on GitHub (pinned to 7944b8e522)
Solutions
- Re-run the command — a fresh server may start via ensureServer
- Check server health/logs (`crush logs`) for the underlying CreateWorkspace error
- Kill stale servers: pkill crush; wait for the socket to disappear, then retry
- If using a remote host, verify connectivity and server-side capacity/auth
Example fix
// before c.ConnectAndUse() // hits a dying server once and fails // after // retry loop already built in; on failure: // pkill -f 'crush serve' && crush # lets ensureServer spawn a fresh server
Defensive patterns
Strategy: retry
Validate before calling
if _, err := c.HealthCheck(ctx); err != nil {
return fmt.Errorf("server unhealthy before workspace creation: %w", err)
} Try / catch
ws, err := c.CreateWorkspace(ctx, req)
if err != nil {
if errors.Is(err, client.ErrServerShuttingDown) {
// wait for replacement server, then retry
}
return fmt.Errorf("failed to create workspace: %w", err)
} Prevention
- Health-check the server before creating workspaces
- Avoid connecting during known shutdown windows (deploys, reboots)
- Keep a supervisor that only ever runs one server per socket
When it happens
Trigger: The remote server rejects CreateWorkspace — workspace limit reached, auth failure, server-side DB error, or the server is mid-shutdown on the last allowed attempt so the error is surfaced instead of retried.
Common situations: A stale crush server process is terminating while the CLI connects; server crashed mid-request; connecting to a server owned by another user/instance that refuses the request; network drop between CLI and HTTP server.
Related errors
- failed to create workspace: server kept shutting down
- not found
- client not attached
- workspace closing
- requested channels differ from the existing workspace; chann
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/ec11f7803e62ab6e.
Report an issue: GitHub.