{"record":{"id":"821c593045401dcb","repo":"charmbracelet/crush","slug":"failed-to-update-agent-status-code-d","errorCode":null,"errorMessage":"failed to update agent: status code %d","messagePattern":"failed to update agent: status code (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":481,"sourceCode":"\tif err := checkStatus(rsp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get agent status: %w\", err)\n\t}\n\tvar info proto.AgentInfo\n\tif err := json.NewDecoder(rsp.Body).Decode(&info); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode agent status: %w\", err)\n\t}\n\treturn &info, nil\n}\n\n// UpdateAgent triggers an agent model update on the server.\nfunc (c *Client) UpdateAgent(ctx context.Context, id string) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/agent/update\", id), nil, nil, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to update agent: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to update agent: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// SendMessage sends a message to the agent for a workspace.\n//\n// When runID is non-empty it is echoed back on the resulting\n// proto.RunComplete event, giving the caller a unique correlator\n// for completion detection. Pass \"\" when the caller does not need\n// to distinguish its own turn's terminal event from any concurrent\n// turn on the same session (e.g. interactive TUI usage).\nfunc (c *Client) SendMessage(ctx context.Context, id string, sessionID, runID, prompt string, attachments ...message.Attachment) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/agent\", id), nil, jsonBody(proto.AgentMessage{\n\t\tSessionID:   sessionID,\n\t\tRunID:       runID,\n\t\tPrompt:      prompt,\n\t\tAttachments: proto.AttachmentsFromMessage(attachments),\n\t}), http.Header{\"Content-Type\": []string{\"application/json\"}})","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L463-L499","documentation":"UpdateAgent expects the server to reply 200 OK to /workspaces/{id}/agent/update. Any other HTTP status (404, 401, 500, etc.) produces this error carrying the numeric status code. Unlike the %w variant, the response body is not decoded, so server-side detail is not included.","triggerScenarios":"Calling UpdateAgent on a workspace id that does not exist (404), with missing/invalid auth (401/403), when the server-side update handler fails (500), or when an older server lacks the /agent/update route.","commonSituations":"Typo'd or recycled workspace id; token expired mid-session; client/server version skew where the route was renamed or removed; server bug during model override.","solutions":["Log the status code and check the server logs for the matching request.","For 404, re-list workspaces to confirm the id still exists before retrying.","For 401/403, refresh credentials/auth token and retry.","For 5xx, retry with backoff; if persistent, check client/server version compatibility."],"exampleFix":"// before\nif err := client.UpdateAgent(ctx, wsID); err != nil {\n    return err\n}\n// after\nif err := client.UpdateAgent(ctx, wsID); err != nil {\n    if strings.Contains(err.Error(), \"status code 404\") {\n        return fmt.Errorf(\"workspace %s no longer exists\", wsID)\n    }\n    return err\n}","handlingStrategy":"fallback","validationCode":"// Go: confirm workspace exists via another endpoint before updating\ninfos, err := client.ListWorkspaces(ctx)\nif err != nil { return err }\nvar found bool\nfor _, w := range infos { if w.ID == workspaceID { found = true } }\nif !found { return fmt.Errorf(\"workspace %q not found\", workspaceID) }","typeGuard":"// Go: extract the status code from the error string\nfunc statusCodeFrom(err error) (int, bool) {\n    var code int\n    n, _ := fmt.Sscanf(err.Error(), \"failed to update agent: status code %d\", &code)\n    return code, n == 1\n}","tryCatchPattern":"if err := client.UpdateAgent(ctx, id); err != nil {\n    if code, ok := statusCodeFrom(err); ok {\n        switch {\n        case code == 401 || code == 403:\n            return refreshAuthAndRetry()\n        case code == 404:\n            return fmt.Errorf(\"workspace %s missing\", id)\n        default:\n            return retryWithBackoff(func() error { return client.UpdateAgent(ctx, id) })\n        }\n    }\n    return err\n}","preventionTips":["Keep auth tokens fresh in long-running clients.","Re-validate workspace IDs after any server restart.","Check client/server version compatibility before calling newer endpoints.","Log status codes on failure so 5xx patterns are visible."],"tags":["http-status","network","agent-update"],"backgroundTag":"unexpected-http-status","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}