charmbracelet/crush · error
status code %d: %s
Error message
status code %d: %s
What it means
checkStatus validates HTTP responses from the client API. When the status code is not in the accepted list and the response body contains an error message, it produces "status code %d: %s" with the server-provided message. This is the client-side representation of a server-side HTTP error.
Source
Thrown at internal/client/errors.go:53
// failure as transient.
ErrUnsupported = errors.New("unsupported by the running server")
)
// checkStatus returns nil when rsp's status code is one of ok
// (http.StatusOK when none are given). Otherwise it returns an error
// carrying the status code and, when the body decodes as a proto.Error,
// the server-provided message. Statuses that callers act on are wrapped
// in the matching sentinel. checkStatus may consume the response body.
func checkStatus(rsp *http.Response, ok ...int) error {
if len(ok) == 0 {
ok = []int{http.StatusOK}
}
if slices.Contains(ok, rsp.StatusCode) {
return nil
}
var err error
if msg := decodeErrorMessage(rsp.Body); msg != "" {
err = fmt.Errorf("status code %d: %s", rsp.StatusCode, msg)
} else {
err = fmt.Errorf("status code %d", rsp.StatusCode)
}
switch rsp.StatusCode {
case http.StatusNotFound:
return fmt.Errorf("%w: %w", ErrNotFound, err)
case http.StatusServiceUnavailable:
return fmt.Errorf("%w: %w", ErrServerShuttingDown, err)
}
return err
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Read the message after the colon — it is the server's own error text and usually names the exact problem.
- Fix the request payload/parameters indicated by the message (e.g. invalid workspace fields).
- Re-authenticate if the status indicates 401/403.
- Check client/server version compatibility if the endpoint is reported as unknown or the request shape is rejected.
Example fix
// before: treating any error generically
ws, err := client.CreateWorkspace(ctx, ws)
if err != nil {
return err
}
// after: inspect status/message for actionable handling
ws, err := client.CreateWorkspace(ctx, ws)
if err != nil {
var statusErr *client.StatusError
if errors.As(err, &statusErr) && statusErr.StatusCode == http.StatusUnauthorized {
return refreshAuthAndRetry(ctx)
}
return fmt.Errorf("create workspace rejected by server: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate request payload before sending
if ws == nil || ws.Path == "" {
return errors.New("workspace path is required")
} Type guard
func isStatusError(err error) (statusCode int, msg string, ok bool) {
// Parse "status code %d: %s" produced by checkStatus
const prefix = "status code "
s := err.Error()
if !strings.HasPrefix(s, prefix) {
return 0, "", false
}
rest := s[len(prefix):]
if idx := strings.IndexByte(rest, ':'); idx >= 0 {
code, e := strconv.Atoi(strings.TrimSpace(rest[:idx]))
return code, strings.TrimSpace(rest[idx+1:]), e == nil
}
code, e := strconv.Atoi(strings.TrimSpace(rest))
return code, "", e == nil
} Try / catch
result, err := client.CreateWorkspace(ctx, ws)
if err != nil {
if code, msg, ok := isStatusError(err); ok {
switch code {
http.StatusUnauthorized, http.StatusForbidden:
return reauthenticate(ctx)
default:
return fmt.Errorf("server rejected request (%d): %s", code, msg)
}
}
return err
} Prevention
- Validate request payloads against the API schema before calling the client.
- Keep auth tokens fresh; re-authenticate on 401/403 before retrying.
- Match client and daemon versions to avoid rejected request shapes.
- Log the full wrapped error message — it contains the server's own explanation.
When it happens
Trigger: Any client call routed through checkStatus (RetireClient, CreateWorkspace, GetWorkspace, SetCurrentSession, SubscribeEvents, and anonymous handlers) receiving a non-OK status where decodeErrorMessage extracts a message from the body — e.g. 400/401/403/409/500 with a JSON error payload.
Common situations: Sending an invalid workspace payload (400), missing or expired auth (401/403), server-side panic (500), or a client/server version mismatch causing the server to reject the request.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- status code %d
- unexpected status code: %d
- failed to list workspaces: status code %d
- failed to get MCP pending auth: status code %d
- failed to get MCP auth URL: status code %d
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/e6e94e2a00cfcba4.
Report an issue: GitHub.