{"record":{"id":"1a1736d7a21074cb","repo":"gastownhall/beads","slug":"failed-to-get-work-item-types-w","errorCode":null,"errorMessage":"failed to get work item types: %w","messagePattern":"failed to get work item types: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/ado/client.go","lineNumber":592,"sourceCode":"\n\tvar envelope listResponse\n\tif err := json.Unmarshal(respBody, &envelope); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse projects response: %w\", err)\n\t}\n\n\tvar projects []Project\n\tif err := json.Unmarshal(envelope.Value, &projects); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse projects value: %w\", err)\n\t}\n\treturn projects, nil\n}\n\n// GetWorkItemTypes returns the work item types available in the project.\nfunc (c *Client) GetWorkItemTypes(ctx context.Context) ([]WorkItemType, error) {\n\turlStr := addAPIVersion(c.apiBase() + \"/wit/workitemtypes\")\n\trespBody, err := c.doRequest(ctx, http.MethodGet, urlStr, \"\", nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get work item types: %w\", err)\n\t}\n\n\tvar envelope listResponse\n\tif err := json.Unmarshal(respBody, &envelope); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse work item types response: %w\", err)\n\t}\n\n\tvar types []WorkItemType\n\tif err := json.Unmarshal(envelope.Value, &types); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse work item types value: %w\", err)\n\t}\n\treturn types, nil\n}\n\n// GetWorkItemStates returns the states for a given work item type.\nfunc (c *Client) GetWorkItemStates(ctx context.Context, typeName string) ([]WorkItemState, error) {\n\turlStr := addAPIVersion(c.apiBase() + \"/wit/workitemtypes/\" + url.PathEscape(typeName) + \"/states\")\n\trespBody, err := c.doRequest(ctx, http.MethodGet, urlStr, \"\", nil)","sourceCodeStart":574,"sourceCodeEnd":610,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/ado/client.go#L574-L610","documentation":"This error wraps an HTTP failure from GET {apiBase}/wit/workitemtypes in GetWorkItemTypes. It fires when the request to list the project's work item types fails at the transport or status level, before any decoding. The cause (401, 404, network, etc.) is wrapped with %w and remains inspectable.","triggerScenarios":"Calling Client.GetWorkItemTypes(ctx) when doRequest fails: invalid/expired PAT (401), wrong project in apiBase (404), missing PAT scope, network failure, or throttling (429).","commonSituations":"PAT without 'Work Items (Read)' scope; client configured for a project that was renamed/deleted; org URL typo; running in a network-isolated CI agent.","solutions":["Check the wrapped error's HTTP status: 401 → fix PAT; 404 → fix project/org URL","Ensure the PAT has Work Items read scope for the organization","Verify the client's project/apiBase configuration points to an existing project","Curl {_org}/{project}/_apis/wit/workitemtypes?api-version=... with the same PAT to isolate library vs environment","Handle 429 throttling by retrying with backoff"],"exampleFix":"// before\ntypes, err := client.GetWorkItemTypes(ctx)\n// after\ntypes, err := client.GetWorkItemTypes(ctx)\nif err != nil && strings.Contains(err.Error(), \"401\") {\n  return fmt.Errorf(\"PAT invalid or missing scope: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// preflight: confirm the project is reachable and PAT works\n_, err := client.GetProject(ctx) // or any cheap project-scoped GET\nif err != nil {\n  return fmt.Errorf(\"project unreachable — check PAT/project config before listing types: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"types, err := client.GetWorkItemTypes(ctx)\nif err != nil {\n  if strings.Contains(err.Error(), \"401\") {\n    return nil, fmt.Errorf(\"PAT invalid/insufficient scope for work item types: %w\", err)\n  }\n  if strings.Contains(err.Error(), \"404\") {\n    return nil, fmt.Errorf(\"project not found — check client project config: %w\", err)\n  }\n  return nil, err\n}","preventionTips":["Grant the PAT Work Items (Read) scope at minimum","Confirm the configured project exists in the org","Handle 429 with retry/backoff for polling workloads","Curl the workitemtypes endpoint once when configuring a new environment"],"tags":["azure-devops","http","work-item-types","authentication"],"backgroundTag":"http-request-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}