gastownhall/beads · error
failed to parse team labels response: %w
Error message
failed to parse team labels response: %w
What it means
After a successful Execute in GetTeamLabels, the raw response bytes are unmarshalled into the anonymous pagination struct. If the JSON does not match that shape, the client wraps the unmarshal error with this message so callers know label page parsing failed, not the HTTP call itself.
Source
Thrown at internal/linear/client.go:714
data, err := c.Execute(ctx, req)
if err != nil {
return nil, fmt.Errorf("failed to fetch team labels: %w", err)
}
var page struct {
Team struct {
Labels *struct {
Nodes []Label `json:"nodes"`
PageInfo struct {
HasNextPage bool `json:"hasNextPage"`
EndCursor string `json:"endCursor"`
} `json:"pageInfo"`
} `json:"labels"`
} `json:"team"`
}
if err := json.Unmarshal(data, &page); err != nil {
return nil, fmt.Errorf("failed to parse team labels response: %w", err)
}
if page.Team.Labels == nil {
return nil, fmt.Errorf("no labels connection found for team")
}
all = append(all, page.Team.Labels.Nodes...)
if !page.Team.Labels.PageInfo.HasNextPage {
break
}
if page.Team.Labels.PageInfo.EndCursor == "" {
break
}
cursor := page.Team.Labels.PageInfo.EndCursor
after = &cursor
}
return all, nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Log/dump the raw `data` bytes on failure to see the actual response shape.
- Verify the request URL is the Linear GraphQL endpoint (https://api.linear.app/graphql).
- Check the Linear changelog for schema changes to `team.labels` and update the anonymous struct accordingly.
- Check for a GraphQL `errors` array in the response — a partial error payload may not match the expected struct.
Example fix
// before
if err := json.Unmarshal(data, &page); err != nil {
return nil, fmt.Errorf("failed to parse team labels response: %w", err)
}
// after
if err := json.Unmarshal(data, &page); err != nil {
return nil, fmt.Errorf("failed to parse team labels response: %w (body: %.200s)", err, data)
} Defensive patterns
Strategy: type-guard
Validate before calling
// ensure the endpoint is the GraphQL API before calling
if !strings.HasSuffix(client.Endpoint, "/graphql") {
return errors.New("endpoint must be https://api.linear.app/graphql")
} Type guard
func parseLabelsSafely(data []byte) (labels []linear.Label, ok bool) {
defer func() { if r := recover(); r != nil { ok = false } }()
var probe struct {
Data struct {
Team struct {
Labels *struct{ Nodes []linear.Label `json:"nodes"` } `json:"labels"`
} `json:"team"`
} `json:"data"`
}
if json.Unmarshal(data, &probe) != nil || probe.Data.Team.Labels == nil {
return nil, false
}
return probe.Data.Team.Labels.Nodes, true
} Try / catch
labels, err := client.GetTeamLabels(ctx)
var uerr *json.UnmarshalTypeError
if errors.As(err, &uerr) {
log.Printf("labels response shape changed: field %s", uerr.Field)
// fall back to cached labels
} Prevention
- Pin and monitor the Linear API version; subscribe to changelog.
- Log raw response bodies on parse failure.
- Never point the client at the REST endpoint.
- Add integration tests that decode a recorded real response.
When it happens
Trigger: Linear returns a payload where data.team.labels doesn't match the expected struct — usually because a GraphQL error partial response was returned, an API version changed field names (e.g. labels → issueLabels), or a proxy returned an HTML/JSON error page.
Common situations: Linear GraphQL schema migrations renaming the labels connection, responses from a wrong endpoint (e.g. hitting the REST API instead of /graphql), HTML error pages from proxies returning 200, malformed JSON truncated responses.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse description search response: %w
- failed to parse create response: %w
- failed to parse update project response: %w
- existing milestone metadata is not a JSON object: %w
- marshaling Linear milestone metadata: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/dba0f1cf1cd8ee85.
Report an issue: GitHub.