charmbracelet/crush · error
failed to run shell command: status code %d
Error message
failed to run shell command: status code %d
What it means
RunShellCommand requires 200 OK. Any other status produces this error with the numeric status code; the response body is not decoded. Common statuses: 404 for unknown workspace/session, 401/403 for auth, 500 for server-side execution failure.
Source
Thrown at internal/client/proto.go:537
var e proto.Error
if err := json.NewDecoder(body).Decode(&e); err != nil {
return ""
}
return e.Message
}
// RunShellCommand runs a shell command in the workspace without triggering the agent.
func (c *Client) RunShellCommand(ctx context.Context, id, sessionID, command string, termWidth int) (proto.ShellCommandResponse, error) {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s/shell", id, sessionID), nil, jsonBody(proto.ShellCommandRequest{
Command: command,
TermWidth: termWidth,
}), http.Header{"Content-Type": []string{"application/json"}})
if err != nil {
return proto.ShellCommandResponse{}, fmt.Errorf("failed to run shell command: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return proto.ShellCommandResponse{}, fmt.Errorf("failed to run shell command: status code %d", rsp.StatusCode)
}
var resp proto.ShellCommandResponse
if err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {
return proto.ShellCommandResponse{}, fmt.Errorf("failed to decode shell command response: %w", err)
}
return resp, nil
}
// GetAgentSessionInfo retrieves the agent session info for a workspace.
func (c *Client) GetAgentSessionInfo(ctx context.Context, id string, sessionID string) (*proto.AgentSession, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s", id, sessionID), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get session agent info: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get session agent info: status code %d", rsp.StatusCode)
}View on GitHub (pinned to 7944b8e522)
Solutions
- For 404, re-acquire a valid session ID (the old one may have been closed).
- For 401/403, refresh credentials.
- For 5xx, inspect server logs; retry with backoff if the command is idempotent.
- Confirm the endpoint exists on the deployed server version.
Example fix
// before
if _, err := client.RunShellCommand(ctx, wsID, sid, cmd, w); err != nil {
return err
}
// after
if _, err := client.RunShellCommand(ctx, wsID, sid, cmd, w); err != nil {
if strings.Contains(err.Error(), "status code 404") {
return fmt.Errorf("session %s closed; re-open session before running commands", sid)
}
return err
} Defensive patterns
Strategy: retry
Validate before calling
// Go: ensure the session exists before running commands
if _, err := client.GetAgentSessionInfo(ctx, wsID, sid); err != nil {
return fmt.Errorf("cannot run command in session %s: %w", sid, err)
} Type guard
// Go: extract and branch on status code
func statusCode(err error) int {
var code int
fmt.Sscanf(err.Error(), "failed to run shell command: status code %d", &code)
return code
} Try / catch
_, err := client.RunShellCommand(ctx, wsID, sid, cmd, w)
if err != nil && statusCode(err) >= 500 {
time.Sleep(2 * time.Second)
_, err = client.RunShellCommand(ctx, wsID, sid, cmd, w) // only retry idempotent commands
}
if err != nil { return err } Prevention
- Only retry on 5xx and only for idempotent commands.
- Treat 404 as 'session closed' and re-open the session.
- Refresh auth on 401/403 instead of retrying blindly.
- Monitor server logs for executor failures matching client 500s.
When it happens
Trigger: Executing a shell command against a non-existent session (404), rejected auth (401/403), or a handler that failed before producing a result (5xx).
Common situations: Session ended/closed on the server while the client still holds its id; token expiry in long tool-running sessions; server error in the command executor.
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/f6a0772ec311cd38.
Report an issue: GitHub.