charmbracelet/crush · error · ErrInvalidClientID
invalid client_id
Error message
invalid client_id
What it means
ErrInvalidClientID reports that a client identifier supplied to a backend operation failed validation. The backend requires every client to present a well-formed client_id when attaching to or acting on a workspace, and validateClientID rejects anything malformed. It is declared as a public sentinel in internal/backend/backend.go so callers can match it with errors.Is.
Source
Thrown at internal/backend/backend.go:37
"github.com/charmbracelet/crush/internal/config"
"github.com/charmbracelet/crush/internal/csync"
"github.com/charmbracelet/crush/internal/db"
"github.com/charmbracelet/crush/internal/proto"
"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 theView on GitHub (pinned to 7944b8e522)
Solutions
- Generate a non-empty client_id (e.g. uuid.NewString()) before calling any backend API
- Verify validateClientID's expected format and conform your ID to it
- Check that your client_id variable is actually populated (no zero-value struct field) before the call
Example fix
// before ws, err := backend.AttachClient(ctx, "", path) // after clientID := uuid.NewString() ws, err := backend.AttachClient(ctx, clientID, path)
Defensive patterns
Strategy: validation
Validate before calling
func validClientID(id string) bool {
if _, err := uuid.Parse(id); err != nil {
return false
}
return strings.TrimSpace(id) != ""
}
if !validClientID(clientID) {
clientID = uuid.NewString()
} Type guard
func isErrInvalidClientID(err error) bool {
return errors.Is(err, backend.ErrInvalidClientID)
} Prevention
- Always generate client IDs with uuid.NewString() at client startup
- Persist the client_id only for the lifetime of a single server connection
- Never pass zero-value strings from config into backend APIs
When it happens
Trigger: Calling AttachClient, DeleteWorkspace, or CreateWorkspace with an empty, whitespace-only, or malformed client_id; TestAttachClient_InvalidID and TestDeleteWorkspace_RejectsBadClientID exercise exactly these paths via validateClientID.
Common situations: Passing an empty string instead of a generated client ID, forgetting to persist a previously generated client_id across reconnects, or hand-rolling an ID with illegal characters instead of a UUID.
Related errors
- prompt is required
- session id missing from context
- agent message id missing from context
- client not attached
- client has been retired
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/bc8e6f6dd0d20231.
Report an issue: GitHub.