charmbracelet/crush · error
failed to answer question batch: %w
Error message
failed to answer question batch: %w
What it means
AnswerQuestionBatch POSTs answers to /workspaces/{id}/questions/answer. This error wraps any transport-level failure from c.post — connection refused, DNS failure, TLS error, or context cancellation — meaning the answers were never delivered. The pending question may still be unresolved.
Source
Thrown at internal/client/proto.go:702
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return false, fmt.Errorf("failed to grant permission: status code %d", rsp.StatusCode)
}
var resp proto.PermissionGrantResponse
if err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {
return false, fmt.Errorf("failed to decode grant permission response: %w", err)
}
return resp.Resolved, nil
}
// AnswerQuestionBatch submits answers for a batch question on a
// workspace. Returns true if this call resolved the pending
// request, false if already resolved by another caller.
func (c *Client) AnswerQuestionBatch(ctx context.Context, id string, req proto.QuestionAnswer) (bool, error) {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/questions/answer", id), nil, jsonBody(req), http.Header{"Content-Type": []string{"application/json"}})
if err != nil {
return false, fmt.Errorf("failed to answer question batch: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return false, fmt.Errorf("failed to answer 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 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 {View on GitHub (pinned to 7944b8e522)
Solutions
- Confirm server connectivity and retry AnswerQuestionBatch; the response's Resolved flag reports whether this call or another caller resolved the question.
- Check the client base URL/port configuration.
- Increase the context timeout if answers time out on large batches.
- Handle a false Resolved return gracefully — another subscriber may have answered first, which is not an error.
Example fix
// before
resolved, err := client.AnswerQuestionBatch(ctx, wsID, answer)
if err != nil { return err }
// after
resolved, err := client.AnswerQuestionBatch(ctx, wsID, answer)
if err != nil {
// safe to retry: answering is idempotent via Resolved flag
return fmt.Errorf("answering question batch on %s: %w", wsID, err)
}
if !resolved { log.Info("question already resolved by another caller") } Defensive patterns
Strategy: retry
Validate before calling
// Ensure the server is reachable and answers are well-formed before sending
if serverReachable(ctx, baseURL) != nil {
return errors.New("cannot answer questions: server unreachable")
} Try / catch
resolved, err := client.AnswerQuestionBatch(ctx, wsID, answer)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) { return err }
return retryAnswerBatch(ctx, wsID, answer, 3) // idempotent via Resolved flag
}
if !resolved { log.Info("question already resolved elsewhere") } Prevention
- Retry answer submissions — the Resolved flag makes them idempotent
- Keep contexts alive long enough for answer round-trips
- Monitor server uptime to distinguish outage from bug
- Handle false Resolved as success, not failure
When it happens
Trigger: Calling AnswerQuestionBatch when the server is down or unreachable, the network drops mid-request, or the caller's context deadline expires before the POST finishes.
Common situations: Server restart between question receipt and answer; user answering on a flaky connection; long-running workspace where the context times out; wrong host/port configuration.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- failed to cancel question batch: %w
- failed to make request: %w
- failed to refresh OAuth token: %w
- failed to check project init: %w
- failed to mark project initialized: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/1affc426886826ae.
Report an issue: GitHub.