gastownhall/beads · error
failed to parse projects value: %w
Error message
failed to parse projects value: %w
What it means
This error means the list envelope decoded but the nested 'value' field could not be unmarshalled into []Project. The top-level JSON looked right, but the items inside 'value' do not match the Project struct (unexpected field types or 'value' not an array).
Source
Thrown at internal/ado/client.go:582
}
// ListProjects returns all team projects in the organization.
// This is an org-level endpoint, not project-scoped.
func (c *Client) ListProjects(ctx context.Context) ([]Project, error) {
urlStr := addAPIVersion(c.orgBase() + "/projects")
respBody, err := c.doRequest(ctx, http.MethodGet, urlStr, "", nil)
if err != nil {
return nil, fmt.Errorf("failed to list projects: %w", err)
}
var envelope listResponse
if err := json.Unmarshal(respBody, &envelope); err != nil {
return nil, fmt.Errorf("failed to parse projects response: %w", err)
}
var projects []Project
if err := json.Unmarshal(envelope.Value, &projects); err != nil {
return nil, fmt.Errorf("failed to parse projects value: %w", err)
}
return projects, nil
}
// GetWorkItemTypes returns the work item types available in the project.
func (c *Client) GetWorkItemTypes(ctx context.Context) ([]WorkItemType, error) {
urlStr := addAPIVersion(c.apiBase() + "/wit/workitemtypes")
respBody, err := c.doRequest(ctx, http.MethodGet, urlStr, "", nil)
if err != nil {
return nil, fmt.Errorf("failed to get work item types: %w", err)
}
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 []WorkItemTypeView on GitHub (pinned to 71377f2769)
Solutions
- Inspect envelope.Value raw JSON and compare against the library's Project struct field types
- Pin/check the api-version the library sends (addAPIVersion) against ADO's current projects schema
- Upgrade the ado package to a version matching the current ADO response schema
- If using a mock/proxy for tests, fix the fixture so 'value' is an array of Project-shaped objects
Example fix
// before (fixture)
{"value": {"id": 1, "name": "p"}}
// after
{"count": 1, "value": [{"id": "abcd-...", "name": "p"}]} Defensive patterns
Strategy: type-guard
Type guard
// validate a projects payload shape before trusting it
type listEnvelope struct {
Count int `json:"count"`
Value json.RawMessage `json:"value"`
}
func projectsPayloadOK(body []byte) bool {
var env listEnvelope
if json.Unmarshal(body, &env) != nil || env.Value == nil {
return false
}
var arr []map[string]any
return json.Unmarshal(env.Value, &arr) == nil
} Try / catch
projects, err := client.ListProjects(ctx)
if err != nil {
if strings.Contains(err.Error(), "failed to parse projects value") {
return nil, fmt.Errorf("ADO projects schema drift — check api-version/library version: %w", err)
}
return nil, err
} Prevention
- Pin the ADO api-version expected by the library version you deploy
- Keep test fixtures in sync with real ADO payloads
- Upgrade the ado package when ADO announces schema changes
- Validate 'value' is an array of object-shaped items in mocks
When it happens
Trigger: Calling ListProjects when ADO's projects payload has items whose fields don't match the Project struct's types (e.g. an 'id' that isn't a string, or 'value' being an object/null instead of an array) — typically after an API version change or schema drift.
Common situations: ADO rolling out an API response change; using an api-version whose schema differs from what the library expects; mocking proxies (e.g. recorded fixtures) returning differently-typed fields.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse work item types value: %w
- failed to parse projects response: %w
- failed to parse work item types response: %w
- failed to parse work item states response: %w
- parsing JSON: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f5445ba42c80c08d.
Report an issue: GitHub.