charmbracelet/crush · error
failed to get session agent info: status code %d
Error message
failed to get session agent info: status code %d
What it means
GetAgentSessionInfo expects 200 OK. Any other status yields this error with the numeric status code, without decoding the body. Typically 404 when the session does not exist or has ended, 401/403 for auth problems, or 5xx for server faults.
Source
Thrown at internal/client/proto.go:554
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)
}
var info proto.AgentSession
if err := json.NewDecoder(rsp.Body).Decode(&info); err != nil {
return nil, fmt.Errorf("failed to decode session agent info: %w", err)
}
return &info, nil
}
// AgentSummarizeSession requests a session summarization.
func (c *Client) AgentSummarizeSession(ctx context.Context, id string, sessionID string) error {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s/summarize", id, sessionID), nil, nil, nil)
if err != nil {
return fmt.Errorf("failed to summarize session: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to summarize session: status code %d", rsp.StatusCode)
}View on GitHub (pinned to 7944b8e522)
Solutions
- For 404, treat the session as terminated — re-create the session rather than retrying.
- For 401/403, refresh credentials and retry once.
- For 5xx, retry with backoff and check server health.
- Verify workspace/session IDs are current; stale IDs from a previous server instance are a frequent cause.
Example fix
// before
info, err := client.GetAgentSessionInfo(ctx, wsID, sid)
if err != nil { return false, err }
// after
info, err := client.GetAgentSessionInfo(ctx, wsID, sid)
if err != nil {
if strings.Contains(err.Error(), "status code 404") {
return false, nil // session gone -> not busy
}
return false, err
} Defensive patterns
Strategy: fallback
Validate before calling
// Go: confirm the session was recently seen before interpreting 404 as terminal
lastSeen, seen := sessionCache[sid]
if seen && time.Since(lastSeen) < time.Minute {
// stale-404 unlikely; treat other statuses first
} Type guard
// Go: branch on 404 vs other statuses
func isNotFound(err error) bool {
return strings.Contains(err.Error(), "status code 404")
} Try / catch
info, err := client.GetAgentSessionInfo(ctx, wsID, sid)
if err != nil {
if isNotFound(err) {
return nil, nil // session ended -> caller treats as 'not busy'
}
if strings.Contains(err.Error(), "status code 401") {
return refreshAuthAndFetch()
}
return nil, err
} Prevention
- Map 404 to 'session gone' semantics in busy-check helpers instead of failing.
- Refresh tokens proactively in long-lived clients to avoid 401 noise.
- For 5xx, retry with backoff; for 4xx, fix the request or IDs.
- Cache session IDs only briefly — they become stale after server restarts.
When it happens
Trigger: Polling session status after the session was closed or expired (404); expired auth token (401/403); server error while assembling AgentSession info (5xx).
Common situations: AgentIsSessionBusy treating a dead session as an error instead of 'not busy'; long-lived clients whose tokens expired; races where the session is deleted between acquiring the id and polling.
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/2069cb5f7ae75140.
Report an issue: GitHub.