gastownhall/beads · error
failed to parse issues response: %w
Error message
failed to parse issues response: %w
What it means
FetchIssues failed to JSON-unmarshal the 'data' payload returned by Linear into IssuesResponse. This means the response shape didn't match the client's expected `issues.nodes`/`pageInfo` structure.
Source
Thrown at internal/linear/client.go:511
"first": MaxPageSize,
}
if cursor != "" {
variables["after"] = cursor
}
req := &GraphQLRequest{
Query: issuesQuery,
Variables: variables,
}
data, err := c.Execute(ctx, req)
if err != nil {
return nil, fmt.Errorf("failed to fetch issues: %w", err)
}
var issuesResp IssuesResponse
if err := json.Unmarshal(data, &issuesResp); err != nil {
return nil, fmt.Errorf("failed to parse issues response: %w", err)
}
allIssues = append(allIssues, issuesResp.Issues.Nodes...)
if !issuesResp.Issues.PageInfo.HasNextPage {
break
}
cursor = issuesResp.Issues.PageInfo.EndCursor
}
return allIssues, nil
}
// FetchIssuesSince retrieves issues from Linear that have been updated since the given time.
// This enables incremental sync by only fetching issues modified after the last sync.
// The state parameter can be: "open", "closed", or "all".
// If ProjectID is set on the client, only issues from that project are returned.
func (c *Client) FetchIssuesSince(ctx context.Context, state string, since time.Time) ([]Issue, error) {View on GitHub (pinned to 71377f2769)
Solutions
- Log the raw data payload (json.RawMessage) to see the actual response shape
- Compare issuesQuery against Linear's current GraphQL schema
- Upgrade the client/beads to a version matching Linear's current API
- If a field type changed, update the Issue/IssuesResponse structs accordingly
Example fix
// after: capture the raw payload for diagnosis
data, err := c.Execute(ctx, req)
if err != nil { return nil, err }
log.Printf("linear raw page: %s", string(data))
var issuesResp IssuesResponse
if err := json.Unmarshal(data, &issuesResp); err != nil {
return nil, fmt.Errorf("failed to parse issues response: %w", err)
} Defensive patterns
Strategy: try-catch
Type guard
// Guard against a truncated/nil issues node before use
func validIssuesResponse(raw json.RawMessage) bool {
var probe struct {
Issues *struct {
PageInfo struct{ HasNextPage bool } `json:"pageInfo"`
} `json:"issues"`
}
return json.Unmarshal(raw, &probe) == nil && probe.Issues != nil
} Try / catch
issues, err := client.FetchIssues(ctx, "all")
if err != nil && strings.Contains(err.Error(), "failed to parse issues response") {
// likely Linear schema drift: capture payload via debug logging, stop retrying
return fmt.Errorf("client/API version mismatch: %w", err)
} Prevention
- Keep the client version current with Linear's API changelog
- Log raw response payloads on parse failure for postmortems
- Avoid mutating the JSON between receive and decode (no rewriting proxies)
- Add a CI smoke test that performs a real (or recorded) fetch and decodes it
When it happens
Trigger: Execute returned successfully but the data payload doesn't fit IssuesResponse: Linear API schema change (fields renamed/removed in issuesQuery), a partial-data response, or unexpected nullability causing decode mismatches.
Common situations: Linear shipped a GraphQL schema change and the vendored client's query/response structs are outdated; a proxy/intercepting layer mangled the JSON; running an old beads binary against a newer Linear API.
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 team states response: %w
- failed to parse issue from JSONL: %w
- failed to parse update project response: %w
- unable to parse plugin file v2: %w
- parsing JSON: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/2f8918b34254aed0.
Report an issue: GitHub.