gastownhall/beads · error
failed to parse teams response: %w
Error message
failed to parse teams response: %w
What it means
After fetching teams successfully at the transport level, FetchTeams unmarshals the JSON into TeamsResponse ({teams:{nodes:[...]}}). This error wraps json.Unmarshal failure — the body's shape didn't match the struct. The library throws it to separate decode problems from request problems.
Source
Thrown at internal/linear/client.go:1433
name
key
}
}
}
`
req := &GraphQLRequest{
Query: query,
}
data, err := c.Execute(ctx, req)
if err != nil {
return nil, fmt.Errorf("failed to fetch teams: %w", err)
}
var teamsResp TeamsResponse
if err := json.Unmarshal(data, &teamsResp); err != nil {
return nil, fmt.Errorf("failed to parse teams response: %w", err)
}
return teamsResp.Teams.Nodes, nil
}
// FetchProjects retrieves projects from Linear with optional filtering by state.
// state can be: "planned", "started", "paused", "completed", "canceled", or "all"/"".
func (c *Client) FetchProjects(ctx context.Context, state string) ([]Project, error) {
var allProjects []Project
var cursor string
filter := map[string]interface{}{
"team": map[string]interface{}{
"id": map[string]interface{}{
"eq": c.TeamID,
},
},
}View on GitHub (pinned to 71377f2769)
Solutions
- Dump the raw `data` payload to inspect the actual JSON structure.
- Check whether the body contains a GraphQL "errors" array and surface that instead of unmarshalling into TeamsResponse.
- Diff the Team/TeamsResponse structs against the current Linear GraphQL schema and update field names/types.
- Bypass any proxy/gateway to confirm the body is genuine GraphQL JSON.
- Update the library/client to a version matching the current Linear API schema.
Example fix
// before
var teamsResp TeamsResponse
if err := json.Unmarshal(data, &teamsResp); err != nil { return nil, err }
// after
var probe map[string]json.RawMessage
if err := json.Unmarshal(data, &probe); err != nil { return nil, err }
if _, ok := probe["teams"]; !ok {
return nil, fmt.Errorf("unexpected teams payload: %s", truncate(string(data), 200))
}
var teamsResp TeamsResponse
if err := json.Unmarshal(data, &teamsResp); err != nil { return nil, err } Defensive patterns
Strategy: type-guard
Type guard
func isTeamsResponse(data []byte) bool {
var probe struct {
Teams *struct{ Nodes []json.RawMessage `json:"nodes"` } `json:"teams"`
}
return json.Unmarshal(data, &probe) == nil && probe.Teams != nil
} Try / catch
teams, err := client.FetchTeams(ctx)
if err != nil {
var ute *json.UnmarshalTypeError
if errors.As(err, &ute) {
return fmt.Errorf("linear schema drift in teams response (field %s): %w", ute.Field, err)
}
return err
} Prevention
- Diff Team/TeamsResponse structs against the live Linear schema after API version bumps.
- Keep a CI integration test calling FetchTeams to catch decode breaks immediately.
- Inspect raw payloads (json.Indent into logs) when a decode error first appears.
- Rule out proxy response substitution by hitting the GraphQL endpoint directly.
When it happens
Trigger: c.Execute succeeded but the payload isn't the expected shape: response is a GraphQL errors envelope with HTTP 200, a proxy returned an HTML page, or TeamsResponse/Team structs no longer match the Linear schema (field renamed, type changed, nullability mismatch causing decode error).
Common situations: Linear API schema evolution breaking generated structs; corporate TLS-inspecting proxy substituting an error page; an API gateway returning JSON error objects; version mismatch between client library and Linear API version.
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 projects response: %w
- failed to parse create project response: %w
- parsing waits-for metadata to set also_blocks: %w
- re-parsing metadata: %w
- ExternalDoltConfig: must set Socket or (Host, Port)
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/96a0009069972c94.
Report an issue: GitHub.