{"record":{"id":"6b6bc8bc239faa2e","repo":"gastownhall/beads","slug":"failed-to-parse-work-item-states-response-w","errorCode":null,"errorMessage":"failed to parse work item states response: %w","messagePattern":"failed to parse work item states response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/ado/client.go","lineNumber":617,"sourceCode":"\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)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get work item states: %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 states response: %w\", err)\n\t}\n\n\tvar states []WorkItemState\n\tif err := json.Unmarshal(envelope.Value, &states); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse work item states value: %w\", err)\n\t}\n\treturn states, nil\n}\n","sourceCodeStart":599,"sourceCodeEnd":626,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/ado/client.go#L599-L626","documentation":"This error means GetWorkItemStates got a response whose body could not be decoded into the listResponse envelope — json.Unmarshal of the raw body failed. The response was not the expected {\"value\": [...]} JSON (HTML page, empty body, or malformed JSON).","triggerScenarios":"Calling GetWorkItemStates when the states endpoint returns non-JSON: HTML auth/proxy page with 200, empty body from a misrouted URL, truncated response, or ADO error page.","commonSituations":"Corporate proxy injecting HTML; incorrect apiBase serving the web UI; network truncation on large responses; ADO degradation.","solutions":["Log the raw response body to see what came back instead of JSON","Ensure requests reach the API host, not an auth proxy or the web UI","Retry transient truncations","Verify project/org URL configuration points at the ADO REST API"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"states, err := client.GetWorkItemStates(ctx, typeName)\nif err != nil {\n  if strings.Contains(err.Error(), \"failed to parse work item states response\") {\n    return nil, fmt.Errorf(\"non-JSON response for states of %q (proxy/HTML page?): %w\", typeName, err)\n  }\n  return nil, err\n}","preventionTips":["Curl the states endpoint once per environment to confirm JSON responses","Bypass or authenticate-through any corporate proxy on dev.azure.com","Retry transient/truncated responses with backoff","Keep the library updated against ADO response-shape changes"],"tags":["json","parsing","azure-devops","response-shape"],"backgroundTag":"json-decode-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}