{"record":{"id":"bfde3705f72e8ba3","repo":"gastownhall/beads","slug":"failed-to-fetch-issue-by-identifier-w","errorCode":null,"errorMessage":"failed to fetch issue by identifier: %w","messagePattern":"failed to fetch issue by identifier: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":1308,"sourceCode":"\t// Extract the issue number from identifier (e.g., \"123\" from \"TEAM-123\")\n\tparts := strings.Split(identifier, \"-\")\n\tif len(parts) >= 2 {\n\t\tif number, err := strconv.Atoi(parts[len(parts)-1]); err == nil {\n\t\t\t// Add number filter for more precise matching\n\t\t\tvariables[\"filter\"].(map[string]interface{})[\"number\"] = map[string]interface{}{\n\t\t\t\t\"eq\": number,\n\t\t\t}\n\t\t}\n\t}\n\n\treq := &GraphQLRequest{\n\t\tQuery:     query,\n\t\tVariables: variables,\n\t}\n\n\tdata, err := c.Execute(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to fetch issue by identifier: %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 issues response: %w\", err)\n\t}\n\n\t// Find the exact match by identifier (in case of partial matches)\n\tfor _, issue := range issuesResp.Issues.Nodes {\n\t\tif issue.Identifier == identifier {\n\t\t\treturn &issue, nil\n\t\t}\n\t}\n\n\treturn nil, nil // Issue not found\n}\n\n// BuildStateCache fetches and caches team states.","sourceCodeStart":1290,"sourceCodeEnd":1326,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L1290-L1326","documentation":"FetchIssueByIdentifier runs an issues(filter:...) GraphQL query to resolve an identifier like TEAM-123. This error wraps any failure from the underlying Execute call: network errors, HTTP errors, GraphQL errors (invalid filter, bad auth), or context cancellation. It does not mean the issue was absent — not-found returns (nil, nil).","triggerScenarios":"c.Execute(ctx, req) returns an error when querying issues with a team/number filter: expired or invalid API key, network failure, rate limiting (429), GraphQL validation error on the IssueFilter, or ctx cancelled/deadline exceeded.","commonSituations":"LINEAR_API_KEY revoked or rotated; expired auth token after long-running sync; rate limit hit during bulk lookups; corporate proxy/DNS blocking linear.app; malformed identifier causing an invalid number filter is NOT this error (it silently skips the filter).","solutions":["Unwrap the error (errors.Unwrap / errors.Is) to see the underlying transport or GraphQL failure.","Verify the Linear API key is valid: run a trivial query like FetchTeams with the same client.","Check rate limits — Linear returns 429 under bulk fetching; back off and retry with jitter.","Confirm network/proxy access to the Linear GraphQL endpoint and retry; the call is idempotent (read-only).","If the wrapped error mentions authentication, regenerate the API key in Linear settings."],"exampleFix":"// before\nissue, err := client.FetchIssueByIdentifier(ctx, \"ENG-123\")\nif err != nil { return err }\n// after\nissue, err := client.FetchIssueByIdentifier(ctx, \"ENG-123\")\nif err != nil {\n    if errors.Is(err, context.DeadlineExceeded) { return retryWithBackoff(...) }\n    return fmt.Errorf(\"lookup ENG-123: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// validate identifier shape before calling\nvar identRe = regexp.MustCompile(`^[A-Za-z0-9]+-\\d+$`)\nif !identRe.MatchString(identifier) {\n    return fmt.Errorf(\"malformed identifier %q; expected TEAM-123\", identifier)\n}","typeGuard":null,"tryCatchPattern":"issue, err := client.FetchIssueByIdentifier(ctx, ident)\nif err != nil {\n    if errors.Is(err, context.DeadlineExceeded) || isNetworkErr(err) {\n        return retryWithBackoff(3, time.Second, func() (*Issue, error) {\n            return client.FetchIssueByIdentifier(ctx, ident)\n        })\n    }\n    return nil, fmt.Errorf(\"lookup %s: %w\", ident, err)\n}\n// note: err == nil && issue == nil means not found","preventionTips":["Remember not-found is (nil, nil), not an error — check both return values.","Use a context with timeout for lookups and inspect errors.Is(err, context.DeadlineExceeded).","Back off on rate-limit errors (Linear 429s) before retrying.","Verify the API key periodically; auth failures surface on the first lookup.","Check errors.As/Is on the wrapped cause before deciding to fail permanently."],"tags":["go","graphql","network","linear-api"],"backgroundTag":"graphql-request-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}