gastownhall/beads · error
failed to parse work item states value: %w
Error message
failed to parse work item states value: %w
What it means
GetWorkItemStates fetched the list of valid states for a work item type from Azure DevOps, but the JSON 'value' array inside the response envelope could not be unmarshaled into []WorkItemState. The HTTP call succeeded, but the response body did not have the expected shape (envelope.value must be a JSON array of state objects with expected field types). This guards callers from a silently nil/partial states list.
Source
Thrown at internal/ado/client.go:622
return types, nil
}
// GetWorkItemStates returns the states for a given work item type.
func (c *Client) GetWorkItemStates(ctx context.Context, typeName string) ([]WorkItemState, error) {
urlStr := addAPIVersion(c.apiBase() + "/wit/workitemtypes/" + url.PathEscape(typeName) + "/states")
respBody, err := c.doRequest(ctx, http.MethodGet, urlStr, "", nil)
if err != nil {
return nil, fmt.Errorf("failed to get work item states: %w", err)
}
var envelope listResponse
if err := json.Unmarshal(respBody, &envelope); err != nil {
return nil, fmt.Errorf("failed to parse work item states response: %w", err)
}
var states []WorkItemState
if err := json.Unmarshal(envelope.Value, &states); err != nil {
return nil, fmt.Errorf("failed to parse work item states value: %w", err)
}
return states, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Verify the organization URL and API version used by the ADO client match a supported Azure DevOps REST version (check ado.url / AZURE_DEVOPS_URL).
- Log/curl the raw response of GET {org}/{project}/_apis/wit/workitemtypes/{type}/states?api-version=... and compare its 'value' entries to the WorkItemState struct field types.
- If behind a proxy or mock, fix the mock to return {"count":N,"value":[{"name":..., "category":..., ...}]}.
- Update the library if Azure DevOps changed the states payload schema.
Example fix
// before: assuming any 200 body is the states envelope
// after: log the raw body when unmarshal fails
if err := json.Unmarshal(envelope.Value, &states); err != nil {
return nil, fmt.Errorf("failed to parse work item states value: %w (body: %.200s)", err, envelope.Value)
} Defensive patterns
Strategy: validation
Validate before calling
resp, _ := http.Get(statesURL)
body, _ := io.ReadAll(resp.Body)
var probe struct {
Value []map[string]json.RawMessage `json:"value"`
}
if json.Unmarshal(body, &probe) != nil || len(probe.Value) == 0 && resp.StatusCode == 200 {
return fmt.Errorf("states endpoint returned unexpected payload")
} Type guard
func isValidStatesEnvelope(body []byte) bool {
var env struct {
Value json.RawMessage `json:"value"`
}
if json.Unmarshal(body, &env) != nil {
return false
}
var states []map[string]interface{}
return json.Unmarshal(env.Value, &states) == nil
} Try / catch
states, err := client.GetWorkItemStates(ctx, project, wit)
if err != nil {
var parseErr *json.UnmarshalTypeError
if errors.As(err, &parseErr) {
log.Printf("ADO states payload shape changed: field %s", parseErr.Field)
return fallbackDefaultStates(wit)
}
return err
} Prevention
- Pin/verify the Azure DevOps api-version used by the client when upgrading.
- Validate proxy/mock endpoints return the standard {count, value} envelope.
- Smoke-test GetWorkItemStates in CI against the real org before relying on state transitions.
When it happens
Trigger: Calling GetWorkItemStates against an ADO organization/process whose response 'value' field is not an array of objects matching the WorkItemState struct (e.g. wrong field types like name as object, or value being a single object).
Common situations: Pointing ado.url at a proxy/mocked ADO endpoint that returns differently shaped JSON; ADO API version changes altering the states payload; hitting a custom inherited process endpoint that returns extra/renamed fields with incompatible types; misconfigured org URL returning an HTML error page for the states route.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse projects response: %w
- failed to parse projects value: %w
- failed to parse work item types response: %w
- failed to parse work item types value: %w
- failed to parse work item states response: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/8cbfcc0185fe644c.
Report an issue: GitHub.