gastownhall/beads · error

failed to get work item types: %w

Error message

failed to get work item types: %w

What it means

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.

Source

Thrown at internal/ado/client.go:592

	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 []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)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped error's HTTP status: 401 → fix PAT; 404 → fix project/org URL
  2. Ensure the PAT has Work Items read scope for the organization
  3. Verify the client's project/apiBase configuration points to an existing project
  4. Curl {_org}/{project}/_apis/wit/workitemtypes?api-version=... with the same PAT to isolate library vs environment
  5. Handle 429 throttling by retrying with backoff

Example fix

// before
types, err := client.GetWorkItemTypes(ctx)
// after
types, err := client.GetWorkItemTypes(ctx)
if err != nil && strings.Contains(err.Error(), "401") {
  return fmt.Errorf("PAT invalid or missing scope: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: confirm the project is reachable and PAT works
_, err := client.GetProject(ctx) // or any cheap project-scoped GET
if err != nil {
  return fmt.Errorf("project unreachable — check PAT/project config before listing types: %w", err)
}

Try / catch

types, err := client.GetWorkItemTypes(ctx)
if err != nil {
  if strings.Contains(err.Error(), "401") {
    return nil, fmt.Errorf("PAT invalid/insufficient scope for work item types: %w", err)
  }
  if strings.Contains(err.Error(), "404") {
    return nil, fmt.Errorf("project not found — check client project config: %w", err)
  }
  return nil, err
}

Prevention

When it happens

Trigger: Calling Client.GetWorkItemTypes(ctx) when doRequest fails: invalid/expired PAT (401), wrong project in apiBase (404), missing PAT scope, network failure, or throttling (429).

Common situations: 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.

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/1a1736d7a21074cb. Report an issue: GitHub.