gastownhall/beads · error
failed to get work item states: %w
Error message
failed to get work item states: %w
What it means
This error wraps an HTTP failure from GET {apiBase}/wit/workitemtypes/{typeName}/states in GetWorkItemStates. The request to list states for a specific work item type failed at the transport/status level; the underlying cause is preserved via %w.
Source
Thrown at internal/ado/client.go:612
var envelope listResponse
if err := json.Unmarshal(respBody, &envelope); err != nil {
return nil, fmt.Errorf("failed to parse work item types response: %w", err)
}
var types []WorkItemType
if err := json.Unmarshal(envelope.Value, &types); err != nil {
return nil, fmt.Errorf("failed to parse work item types value: %w", err)
}
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 typeName exists by calling GetWorkItemTypes first (404 usually means the type isn't in this project's process template)
- Check the wrapped error's status code to distinguish auth (401) from not-found (404)
- Confirm the project configuration in the client matches where the type lives
- Use the exact type name as returned by the API (custom templates may rename types)
- Retry on 429/5xx with backoff
Example fix
// before
states, err := client.GetWorkItemStates(ctx, "Epic") // project uses Scrum: no Epic
// after
types, _ := client.GetWorkItemTypes(ctx)
if !containsType(types, "Epic") {
return nil, fmt.Errorf("work item type %q not available in project", "Epic")
}
states, err := client.GetWorkItemStates(ctx, "Epic") Defensive patterns
Strategy: validation
Validate before calling
// verify the type exists in this project before asking for its states
types, err := client.GetWorkItemTypes(ctx)
if err != nil {
return err
}
found := false
for _, t := range types {
if t.Name == typeName || t.ReferenceName == typeName {
found = true
break
}
}
if !found {
return fmt.Errorf("work item type %q not present in project's process template", typeName)
} Type guard
func hasWorkItemType(types []ado.WorkItemType, name string) bool {
for _, t := range types {
if t.Name == name {
return true
}
}
return false
} Try / catch
states, err := client.GetWorkItemStates(ctx, typeName)
if err != nil {
if strings.Contains(err.Error(), "404") {
return nil, fmt.Errorf("type %q not found in project — check process template: %w", typeName, err)
}
return nil, err
} Prevention
- Pass type names exactly as returned by GetWorkItemTypes
- Remember custom process templates can rename or omit types (Agile/Scrum/CMMI differ)
- Cache the type list per project instead of hardcoding type names
- Handle 429 throttling in polling loops
When it happens
Trigger: Calling Client.GetWorkItemStates(ctx, typeName) when doRequest fails: typeName that doesn't exist (404), typeName needing escaping but corrupt after PathEscape, invalid PAT (401), missing project (404), network error, 429 throttling.
Common situations: Passing a display name for a type absent from the project's process template (e.g. 'Epic' in a project using Scrum vs Agile); typo in type name; renamed custom types; PAT scope issues.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- failed to list projects: %w
- invalid pull filter: %w
- transient error %d (attempt %d/%d)
- max retries (%d) exceeded: %w
- failed to fetch work items: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b2b67ea39eef19ea.
Report an issue: GitHub.