gastownhall/beads · error
failed to parse batch create response: %w
Error message
failed to parse batch create response: %w
What it means
BatchCreateIssues received a successful HTTP response for the issueBatchCreate mutation but json.Unmarshal could not decode it into IssueBatchCreateResponse. Unlike error-path failures, this branch does NOT run recovery search — the library treats an undecodable success response as a hard parse failure and returns the issues from earlier chunks plus this error.
Source
Thrown at internal/linear/client.go:1091
},
}
data, err := c.Execute(ctx, req)
if err != nil {
found, recoverErr := c.recoverAfterAmbiguousBatch(ctx, chunk)
if recoverErr != nil {
return allIssues, fmt.Errorf("batch create failed and recovery search also failed: %w (batch error: %v)", recoverErr, err)
}
allIssues = append(allIssues, found...)
if len(found) < len(chunk) {
return allIssues, fmt.Errorf("batch create failed; %d of %d issues unconfirmed (batch error: %v)", len(chunk)-len(found), len(chunk), err)
}
continue
}
var batchResp IssueBatchCreateResponse
if err := json.Unmarshal(data, &batchResp); err != nil {
return allIssues, fmt.Errorf("failed to parse batch create response: %w", err)
}
if !batchResp.IssueBatchCreate.Success {
found, recoverErr := c.recoverAfterAmbiguousBatch(ctx, chunk)
if recoverErr != nil {
return allIssues, fmt.Errorf("batch create unsuccessful and recovery search also failed: %w", recoverErr)
}
allIssues = append(allIssues, found...)
if len(found) < len(chunk) {
return allIssues, fmt.Errorf("batch create unsuccessful; %d of %d issues unconfirmed", len(chunk)-len(found), len(chunk))
}
continue
}
allIssues = append(allIssues, batchResp.IssueBatchCreate.Issues...)
}
return allIssues, nilView on GitHub (pinned to 71377f2769)
Solutions
- Retry the batch with the same idempotency markers — either the request never landed (safe) or recovery markers let you reconcile.
- Log the raw response body to identify whether the payload is HTML, truncated, or shaped differently.
- Upgrade the library to a version matching the current Linear GraphQL schema.
- Check proxies/gateways between the client and api.linear.app that may rewrite responses.
Example fix
// before
issues, err := client.BatchCreateIssues(ctx, inputs)
if err != nil {
return err
}
// after
issues, err := client.BatchCreateIssues(ctx, inputs)
if err != nil {
if strings.Contains(err.Error(), "failed to parse batch create response") {
// response undecodable: retry with same markers; earlier chunks already returned
return fmt.Errorf("batch response undecodable, retry idempotently: %w", err)
}
return err
} Defensive patterns
Strategy: retry
Validate before calling
// No caller-side validation prevents a malformed response; ensure inputs are serializable and the endpoint is reachable
if len(inputs) == 0 {
return nil
} Type guard
func isBatchParseFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to parse batch create response")
} Try / catch
issues, err := client.BatchCreateIssues(ctx, inputs)
if isBatchParseFailure(err) {
// undecodable success response: retry with same markers; earlier chunks already in hand
issues2, err2 := client.BatchCreateIssues(ctx, inputs)
_ = issues2
_ = err2
} Prevention
- Bypass or configure proxies that may substitute non-JSON bodies.
- Pin/upgrade the library to match the current Linear GraphQL schema.
- Retry idempotently with unchanged markers so re-runs stay safe.
- Capture raw response bodies (via a wrapped transport) for post-mortem on parse failures.
When it happens
Trigger: Calling Client.BatchCreateIssues when Linear returns a body that fails to unmarshal into the expected issues/success envelope: non-JSON payload (proxy HTML page), truncated body, or a schema drift adding/renaming fields the struct cannot accommodate.
Common situations: API gateway interference substituting HTML for JSON; SDK/Linear schema version drift; response truncated on unstable networks; mocking transport in tests returning fixtures that don't match IssueBatchCreateResponse.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse update response: %w
- batch create failed and recovery search also failed: %w (bat
- batch create failed; %d of %d issues unconfirmed (batch erro
- failed to fetch issue by identifier: %w
- failed to fetch teams: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/cad43ed6a28447fd.
Report an issue: GitHub.