{"record":{"id":"1f4004b6bd836941","repo":"gastownhall/beads","slug":"failed-to-parse-description-search-response-w","errorCode":null,"errorMessage":"failed to parse description search response: %w","messagePattern":"failed to parse description search response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":786,"sourceCode":"\t\t\t\"contains\": text,\n\t\t},\n\t}\n\n\treq := &GraphQLRequest{\n\t\tQuery: query,\n\t\tVariables: map[string]interface{}{\n\t\t\t\"filter\": filter,\n\t\t},\n\t}\n\n\tdata, err := c.Execute(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to search issues by description: %w\", err)\n\t}\n\n\tvar issuesResp IssuesResponse\n\tif err := json.Unmarshal(data, &issuesResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse description search response: %w\", err)\n\t}\n\n\tif len(issuesResp.Issues.Nodes) > 0 {\n\t\treturn &issuesResp.Issues.Nodes[0], nil\n\t}\n\treturn nil, nil\n}\n\n// issueCreateMutation is the GraphQL mutation for creating a Linear issue.\nconst issueCreateMutation = `\n\tmutation CreateIssue($input: IssueCreateInput!) {\n\t\tissueCreate(input: $input) {\n\t\t\tsuccess\n\t\t\tissue {\n\t\t\t\tid\n\t\t\t\tidentifier\n\t\t\t\ttitle\n\t\t\t\tdescription","sourceCodeStart":768,"sourceCodeEnd":804,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L768-L804","documentation":"Once the description-search query succeeds, the response bytes are unmarshalled into IssuesResponse. This error wraps a JSON unmarshal failure, meaning the HTTP call worked but the body does not match the expected `{ issues: { nodes: [...] } }` shape.","triggerScenarios":"Linear returns 200 with a body that doesn't fit IssuesResponse — GraphQL error partial payloads, schema changes to the issues connection, proxy/HTML error bodies with a 200 status, or truncated responses.","commonSituations":"Hitting the wrong endpoint (REST instead of /graphql), corporate proxies returning HTML interstitials, Linear schema updates renaming `issues` or `nodes`, mid-request connection drops producing truncated JSON.","solutions":["Log the raw response body alongside the unmarshal error to see the actual payload.","Confirm the endpoint URL is https://api.linear.app/graphql.","Check for and surface any GraphQL `errors` array in the response before/instead of unmarshalling.","Update IssuesResponse struct fields if the Linear schema changed."],"exampleFix":"// before\nif err := json.Unmarshal(data, &issuesResp); err != nil {\n    return nil, fmt.Errorf(\"failed to parse description search response: %w\", err)\n}\n// after\nif err := json.Unmarshal(data, &issuesResp); err != nil {\n    return nil, fmt.Errorf(\"failed to parse description search response: %w (body: %.200s)\", err, data)\n}","handlingStrategy":"type-guard","validationCode":"// verify endpoint before search\nif client.Endpoint != \"https://api.linear.app/graphql\" {\n    return errors.New(\"unexpected Linear endpoint\")\n}","typeGuard":"func validIssuesPayload(data []byte) bool {\n    var probe struct {\n        Issues *struct {\n            Nodes []json.RawMessage `json:\"nodes\"`\n        } `json:\"issues\"`\n    }\n    return json.Unmarshal(data, &probe) == nil && probe.Issues != nil\n}","tryCatchPattern":"issue, err := client.FindIssueByDescriptionContains(ctx, desc)\nif err != nil {\n    var typeErr *json.UnmarshalTypeError\n    if errors.As(err, &typeErr) {\n        log.Printf(\"unexpected search response shape at %s; skipping dedupe\", typeErr.Field)\n        return nil // proceed without dedupe or use cache\n    }\n    return err\n}","preventionTips":["Log raw response bodies when parsing fails.","Block HTML error pages by checking Content-Type before unmarshal.","Add golden-file tests decoding real Linear responses.","Monitor Linear API changelog for issues-connection changes."],"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"}