charmbracelet/crush · error
failed to cancel question batch: status code %d
Error message
failed to cancel question batch: status code %d
What it means
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.
Source
Thrown at internal/client/proto.go:725
}
var resp proto.QuestionAnswerResponse
if err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {
return false, fmt.Errorf("failed to decode answer question batch response: %w", err)
}
return resp.Resolved, nil
}
// CancelQuestionBatch cancels the pending question batch on a
// workspace. Returns true if a question was cancelled, false if
// none was pending.
func (c *Client) CancelQuestionBatch(ctx context.Context, id string) (bool, error) {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/questions/cancel", id), nil, nil, http.Header{})
if err != nil {
return false, fmt.Errorf("failed to cancel question batch: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return false, fmt.Errorf("failed to cancel question batch: status code %d", rsp.StatusCode)
}
var resp proto.QuestionAnswerResponse
if err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {
return false, fmt.Errorf("failed to decode cancel question batch response: %w", err)
}
return resp.Resolved, nil
}
// SetPermissionsSkipRequests sets the skip-requests flag for a workspace.
func (c *Client) SetPermissionsSkipRequests(ctx context.Context, id string, skip bool) error {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/permissions/skip", id), nil, jsonBody(proto.PermissionSkipRequest{Skip: skip}), http.Header{"Content-Type": []string{"application/json"}})
if err != nil {
return fmt.Errorf("failed to set permissions skip requests: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to set permissions skip requests: status code %d", rsp.StatusCode)
}View on GitHub (pinned to 7944b8e522)
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.
Defensive patterns
Strategy: try-catch
Type guard
func isCancelStatusError(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to cancel question batch: status code")
} Try / catch
ok, err := client.CancelQuestionBatch(ctx, wsID)
if isCancelStatusError(err) {
switch {
case strings.Contains(err.Error(), "401"), strings.Contains(err.Error(), "403"):
return reauthenticateAndRetryCancel(ctx, wsID)
case strings.Contains(err.Error(), "404"):
log.Warn("workspace gone; cancel moot", "ws", wsID)
return nil
default:
return err
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Stale workspace id after reconnect; token expiry; server upgrade moving the route; 500 during question-state cleanup.
Related errors
- failed to answer question batch: status code %d
- failed to grant permission: status code %d
- failed to refresh OAuth token: status code %d
- failed to check project init: status code %d
- failed to mark project initialized: status code %d
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/1fb9a1abea88066e.
Report an issue: GitHub.