{"record":{"id":"dba0f1cf1cd8ee85","repo":"gastownhall/beads","slug":"failed-to-parse-team-labels-response-w","errorCode":null,"errorMessage":"failed to parse team labels response: %w","messagePattern":"failed to parse team labels response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":714,"sourceCode":"\n\t\tdata, err := c.Execute(ctx, req)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to fetch team labels: %w\", err)\n\t\t}\n\n\t\tvar page struct {\n\t\t\tTeam struct {\n\t\t\t\tLabels *struct {\n\t\t\t\t\tNodes    []Label `json:\"nodes\"`\n\t\t\t\t\tPageInfo struct {\n\t\t\t\t\t\tHasNextPage bool   `json:\"hasNextPage\"`\n\t\t\t\t\t\tEndCursor   string `json:\"endCursor\"`\n\t\t\t\t\t} `json:\"pageInfo\"`\n\t\t\t\t} `json:\"labels\"`\n\t\t\t} `json:\"team\"`\n\t\t}\n\t\tif err := json.Unmarshal(data, &page); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse team labels response: %w\", err)\n\t\t}\n\t\tif page.Team.Labels == nil {\n\t\t\treturn nil, fmt.Errorf(\"no labels connection found for team\")\n\t\t}\n\n\t\tall = append(all, page.Team.Labels.Nodes...)\n\t\tif !page.Team.Labels.PageInfo.HasNextPage {\n\t\t\tbreak\n\t\t}\n\t\tif page.Team.Labels.PageInfo.EndCursor == \"\" {\n\t\t\tbreak\n\t\t}\n\t\tcursor := page.Team.Labels.PageInfo.EndCursor\n\t\tafter = &cursor\n\t}\n\n\treturn all, nil\n}","sourceCodeStart":696,"sourceCodeEnd":732,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L696-L732","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nif err := json.Unmarshal(data, &page); err != nil {\n    return nil, fmt.Errorf(\"failed to parse team labels response: %w\", err)\n}\n// after\nif err := json.Unmarshal(data, &page); err != nil {\n    return nil, fmt.Errorf(\"failed to parse team labels response: %w (body: %.200s)\", err, data)\n}","handlingStrategy":"type-guard","validationCode":"// ensure the endpoint is the GraphQL API before calling\nif !strings.HasSuffix(client.Endpoint, \"/graphql\") {\n    return errors.New(\"endpoint must be https://api.linear.app/graphql\")\n}","typeGuard":"func parseLabelsSafely(data []byte) (labels []linear.Label, ok bool) {\n    defer func() { if r := recover(); r != nil { ok = false } }()\n    var probe struct {\n        Data struct {\n            Team struct {\n                Labels *struct{ Nodes []linear.Label `json:\"nodes\"` } `json:\"labels\"`\n            } `json:\"team\"`\n        } `json:\"data\"`\n    }\n    if json.Unmarshal(data, &probe) != nil || probe.Data.Team.Labels == nil {\n        return nil, false\n    }\n    return probe.Data.Team.Labels.Nodes, true\n}","tryCatchPattern":"labels, err := client.GetTeamLabels(ctx)\nvar uerr *json.UnmarshalTypeError\nif errors.As(err, &uerr) {\n    log.Printf(\"labels response shape changed: field %s\", uerr.Field)\n    // fall back to cached labels\n}","preventionTips":["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."],"tags":["json","unmarshal","linear","schema-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}