{"record":{"id":"1fb9a1abea88066e","repo":"charmbracelet/crush","slug":"failed-to-cancel-question-batch-status-code-d","errorCode":null,"errorMessage":"failed to cancel question batch: status code %d","messagePattern":"failed to cancel question batch: status code (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":725,"sourceCode":"\t}\n\tvar resp proto.QuestionAnswerResponse\n\tif err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {\n\t\treturn false, fmt.Errorf(\"failed to decode answer question batch response: %w\", err)\n\t}\n\treturn resp.Resolved, nil\n}\n\n// CancelQuestionBatch cancels the pending question batch on a\n// workspace. Returns true if a question was cancelled, false if\n// none was pending.\nfunc (c *Client) CancelQuestionBatch(ctx context.Context, id string) (bool, error) {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/questions/cancel\", id), nil, nil, http.Header{})\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"failed to cancel question batch: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn false, fmt.Errorf(\"failed to cancel question batch: status code %d\", rsp.StatusCode)\n\t}\n\tvar resp proto.QuestionAnswerResponse\n\tif err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {\n\t\treturn false, fmt.Errorf(\"failed to decode cancel question batch response: %w\", err)\n\t}\n\treturn resp.Resolved, nil\n}\n\n// SetPermissionsSkipRequests sets the skip-requests flag for a workspace.\nfunc (c *Client) SetPermissionsSkipRequests(ctx context.Context, id string, skip bool) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/permissions/skip\", id), nil, jsonBody(proto.PermissionSkipRequest{Skip: skip}), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to set permissions skip requests: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to set permissions skip requests: status code %d\", rsp.StatusCode)\n\t}","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L707-L743","documentation":"CancelQuestionBatch expects HTTP 200 from /workspaces/{id}/questions/cancel. Any other status code produces this error. The server rejected the cancel, so a pending batch (if any) was not cancelled by this request.","triggerScenarios":"POSTing a cancel with a nonexistent workspace id (404), missing/expired auth (401/403), or hitting a server error (5xx); also 4xx if the endpoint contract changed between versions.","commonSituations":"Stale workspace id after reconnect; token expiry; server upgrade moving the route; 500 during question-state cleanup.","solutions":["Identify the status code from the error message: re-authenticate for 401/403, re-resolve the workspace id for 404, check server logs for 5xx.","Confirm the workspace id is current.","Refresh credentials if expired.","Check client/server version compatibility and upgrade the mismatched side."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isCancelStatusError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"failed to cancel question batch: status code\")\n}","tryCatchPattern":"ok, err := client.CancelQuestionBatch(ctx, wsID)\nif isCancelStatusError(err) {\n\tswitch {\n\tcase strings.Contains(err.Error(), \"401\"), strings.Contains(err.Error(), \"403\"):\n\t\treturn reauthenticateAndRetryCancel(ctx, wsID)\n\tcase strings.Contains(err.Error(), \"404\"):\n\t\tlog.Warn(\"workspace gone; cancel moot\", \"ws\", wsID)\n\t\treturn nil\n\tdefault:\n\t\treturn err\n\t}\n}","preventionTips":["Resolve workspace ids from the server, never hardcode","Re-authenticate before token expiry mid-session","Track server upgrades and update clients in lockstep","Surface the embedded status code in your own logs"],"tags":["http-client","http-status","questions","api"],"backgroundTag":"http-non-200-response","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}