charmbracelet/crush · error
failed to get messages: status code %d
Error message
failed to get messages: status code %d
What it means
Thrown by Client.ListMessages when the server returned a status other than 200 for GET /workspaces/{id}/sessions/{sessionID}/messages. The response body is not read, so only the numeric status is available. During restoreModelFromSession this prevents the conversation history from being restored.
Source
Thrown at internal/client/proto.go:598
if err != nil {
return fmt.Errorf("failed to initiate session agent processing: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to initiate session agent processing: status code %d", rsp.StatusCode)
}
return nil
}
// ListMessages retrieves all messages for a session as proto types.
func (c *Client) ListMessages(ctx context.Context, id string, sessionID string) ([]proto.Message, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/sessions/%s/messages", id, sessionID), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get messages: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get messages: status code %d", rsp.StatusCode)
}
var msgs []proto.Message
if err := json.NewDecoder(rsp.Body).Decode(&msgs); err != nil && !errors.Is(err, io.EOF) {
return nil, fmt.Errorf("failed to decode messages: %w", err)
}
return msgs, nil
}
// GetSession retrieves a specific session as a proto type.
func (c *Client) GetSession(ctx context.Context, id string, sessionID string) (*proto.Session, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/sessions/%s", id, sessionID), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get session: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get session: status code %d", rsp.StatusCode)
}View on GitHub (pinned to 7944b8e522)
Solutions
- Check the status code embedded in the error: 404 means the session is gone — start a new session or pick a different one.
- Verify the workspace id matches the one the session was created under.
- Re-authenticate if the status is 401/403.
- Check server logs and retry if the status is 5xx (transient server fault).
Example fix
// before
msgs, err := client.ListMessages(ctx, wsID, sessionID)
if err != nil {
return fmt.Errorf("restore failed: %w", err)
}
// after: distinguish missing session from transient failure
msgs, err := client.ListMessages(ctx, wsID, sessionID)
if err != nil {
if strings.Contains(err.Error(), "status code 404") {
return ErrSessionNotFound
}
return fmt.Errorf("restore failed, retrying may help: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
// Confirm the session exists before restoring messages
sessions, err := client.ListSessions(ctx, wsID)
if err != nil {
return err
}
found := false
for _, s := range sessions {
if s.ID == sessionID {
found = true
break
}
}
if !found {
return fmt.Errorf("session %s not in workspace %s", sessionID, wsID)
} Type guard
func listMessagesStatus(err error) int {
var code int
if _, scanErr := fmt.Sscanf(err.Error(), "failed to get messages: status code %d", &code); scanErr == nil {
return code
}
return 0
} Try / catch
msgs, err := client.ListMessages(ctx, wsID, sessionID)
if err != nil {
if listMessagesStatus(err) == 404 {
return startFreshSession(ctx) // graceful degradation
}
return fmt.Errorf("message restore failed: %w", err)
} Prevention
- List sessions first and verify the id before fetching messages
- Map 404 to a 'start new session' path instead of failing the restore
- Keep workspace ids consistent between machines to avoid cross-workspace 404s
- Refresh auth credentials when seeing 401/403 statuses
When it happens
Trigger: Calling ListMessages for a sessionID that does not exist (404), an invalid workspace id, auth rejection (401/403), or a server-side failure while enumerating messages (500).
Common situations: Restoring a session that was deleted on another machine; workspace id drift after re-cloning or moving the project; expired auth token; server bug or DB corruption producing 500.
Related errors
- request failed with status code: %d
- failed to summarize session: status code %d
- failed to initiate session agent processing: status code %d
- unexpected status code: %d
- failed to refresh MCP tools: status code %d
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/de935f37a1606e1d.
Report an issue: GitHub.