charmbracelet/crush · warning · ErrServerNotIdle
server is hosting live workspaces
Error message
server is hosting live workspaces
What it means
ErrServerNotIdle reports that a shutdown request was refused because the server is still hosting live workspaces (or is midway through creating one). Shutdown is only permitted when the server has nothing in flight; the backend returns this from handlePostControl to protect running work. The client-side equivalent is ErrServerBusy.
Source
Thrown at internal/backend/backend.go:41
"github.com/charmbracelet/crush/internal/skills"
"github.com/charmbracelet/crush/internal/ui/util"
"github.com/charmbracelet/crush/internal/version"
"github.com/google/uuid"
)
// Common errors returned by backend operations.
var (
ErrWorkspaceNotFound = errors.New("workspace not found")
ErrLSPClientNotFound = errors.New("LSP client not found")
ErrAgentNotInitialized = errors.New("agent coordinator not initialized")
ErrPathRequired = errors.New("path is required")
ErrInvalidPermissionAction = errors.New("invalid permission action")
ErrUnknownCommand = errors.New("unknown command")
ErrInvalidClientID = errors.New("invalid client_id")
ErrClientNotAttached = errors.New("client not attached")
ErrWorkspaceClosing = errors.New("workspace closing")
ErrServerShuttingDown = errors.New("server is shutting down")
ErrServerNotIdle = errors.New("server is hosting live workspaces")
ErrClientRetired = errors.New("client has been retired")
ErrChannelOptInMismatch = errors.New("requested channels differ from the existing workspace; channels are an explicit opt-in and are not shared across duplicate creates")
)
// DefaultCreateGrace is the window in which a client must open an SSE
// stream after creating a workspace before its creation hold is
// released. Exposed as a package variable so tests can shorten it.
var DefaultCreateGrace = 30 * time.Second
// DefaultIdleShutdownDelay is how long the server stays alive after its
// last workspace is released before it shuts itself down. The delay
// exists so a client that closes one session and opens another moments
// later (the same directory or a different one) reuses the still-running
// server instead of racing its shutdown: with an immediate shutdown the
// new client can attach to — or create a workspace on — a server that is
// already tearing down, and then observe its coder agent as "offline".
// Any workspace create within the window cancels the pending shutdown.
// Overridable via CRUSH_SERVER_IDLE_TIMEOUT (seconds; 0 restores theView on GitHub (pinned to 7944b8e522)
Solutions
- Release/teardown all live workspaces first, then retry the shutdown
- Treat the refusal as 'keep using the server' — continue working against it instead of forcing exit
- Wait out DefaultCreateGrace (30s) or the in-flight create before retrying
Example fix
// before
if err := client.ShutdownServerIfIdle(ctx); err != nil { return err }
// after
if err := client.ShutdownServerIfIdle(ctx); err != nil {
if errors.Is(err, client.ErrServerBusy) {
return nil // keep using the server; it still has live workspaces
}
return err
} Defensive patterns
Strategy: retry
Type guard
func isErrServerNotIdle(err error) bool {
return errors.Is(err, backend.ErrServerNotIdle)
} Try / catch
for {
err := client.ShutdownServerIfIdle(ctx)
if err == nil || !errors.Is(err, client.ErrServerBusy) {
return err
}
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(time.Second):
}
} Prevention
- Release every workspace before requesting shutdown
- Wait out the create-grace window (30s) when a create was recently issued
- Coordinate shutdown across all clients sharing the server
When it happens
Trigger: Posting a control shutdown request (handlePostControl) while at least one live workspace exists or a workspace create is in its grace window; calling ShutdownServerIfIdle on a server with active clients.
Common situations: A version-mismatched client asking the server to stand down while other clients still use it; automation scripts stopping the shared server while an editor session is open; create grace (DefaultCreateGrace) still ticking for a workspace the caller forgot about.
Related errors
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/cdb4c8639cf6f0d3.
Report an issue: GitHub.