{"record":{"id":"de935f37a1606e1d","repo":"charmbracelet/crush","slug":"failed-to-get-messages-status-code-d","errorCode":null,"errorMessage":"failed to get messages: status code %d","messagePattern":"failed to get messages: status code (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":598,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to initiate session agent processing: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to initiate session agent processing: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// ListMessages retrieves all messages for a session as proto types.\nfunc (c *Client) ListMessages(ctx context.Context, id string, sessionID string) ([]proto.Message, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/sessions/%s/messages\", id, sessionID), nil, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get messages: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to get messages: status code %d\", rsp.StatusCode)\n\t}\n\tvar msgs []proto.Message\n\tif err := json.NewDecoder(rsp.Body).Decode(&msgs); err != nil && !errors.Is(err, io.EOF) {\n\t\treturn nil, fmt.Errorf(\"failed to decode messages: %w\", err)\n\t}\n\treturn msgs, nil\n}\n\n// GetSession retrieves a specific session as a proto type.\nfunc (c *Client) GetSession(ctx context.Context, id string, sessionID string) (*proto.Session, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/sessions/%s\", id, sessionID), nil, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get session: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to get session: status code %d\", rsp.StatusCode)\n\t}","sourceCodeStart":580,"sourceCodeEnd":616,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L580-L616","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"// before\nmsgs, err := client.ListMessages(ctx, wsID, sessionID)\nif err != nil {\n    return fmt.Errorf(\"restore failed: %w\", err)\n}\n// after: distinguish missing session from transient failure\nmsgs, err := client.ListMessages(ctx, wsID, sessionID)\nif err != nil {\n    if strings.Contains(err.Error(), \"status code 404\") {\n        return ErrSessionNotFound\n    }\n    return fmt.Errorf(\"restore failed, retrying may help: %w\", err)\n}","handlingStrategy":"validation","validationCode":"// Confirm the session exists before restoring messages\nsessions, err := client.ListSessions(ctx, wsID)\nif err != nil {\n    return err\n}\nfound := false\nfor _, s := range sessions {\n    if s.ID == sessionID {\n        found = true\n        break\n    }\n}\nif !found {\n    return fmt.Errorf(\"session %s not in workspace %s\", sessionID, wsID)\n}","typeGuard":"func listMessagesStatus(err error) int {\n    var code int\n    if _, scanErr := fmt.Sscanf(err.Error(), \"failed to get messages: status code %d\", &code); scanErr == nil {\n        return code\n    }\n    return 0\n}","tryCatchPattern":"msgs, err := client.ListMessages(ctx, wsID, sessionID)\nif err != nil {\n    if listMessagesStatus(err) == 404 {\n        return startFreshSession(ctx) // graceful degradation\n    }\n    return fmt.Errorf(\"message restore failed: %w\", err)\n}","preventionTips":["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"],"tags":["http","status-code","messages","server-error"],"backgroundTag":"unexpected-http-status","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}