gastownhall/beads · error
request failed: %w
Error message
request failed: %w
What it means
This error wraps a failure of c.HTTPClient.Do(httpReq) — the HTTP request to Linear's API never completed with a response. Typical causes are DNS failures, connection refused/timeouts, TLS problems, or the context being canceled mid-flight. It is a transport-level failure, distinct from API errors returned with an HTTP status.
Source
Thrown at internal/linear/client.go:895
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %w", err)
}
httpReq, err := http.NewRequestWithContext(ctx, "POST", c.Endpoint, bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
authValue, err := c.authHeader()
if err != nil {
return nil, err
}
httpReq.Header.Set("Authorization", authValue)
resp, err := c.HTTPClient.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
respBody, err := io.ReadAll(io.LimitReader(resp.Body, MaxResponseSize))
_ = resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("API error: %s (status %d)", string(respBody), resp.StatusCode)
}
var gqlResp struct {
Data json.RawMessage `json:"data"`
Errors []GraphQLError `json:"errors,omitempty"`
}
if err := json.Unmarshal(respBody, &gqlResp); err != nil {
return nil, fmt.Errorf("failed to parse response: %w (body: %s)", err, string(respBody))View on GitHub (pinned to 71377f2769)
Solutions
- Check network reachability: curl https://api.linear.app/graphql from the same host
- Inspect the wrapped cause (net.Error, context.DeadlineExceeded, x509 errors) via errors.As and handle each class
- Increase the HTTP client timeout or retry on transient network errors with backoff
- Verify proxy environment variables (HTTP_PROXY/HTTPS_PROXY) and TLS trust store are correct
Example fix
// before
client := &http.Client{} // no timeout; hangs then fails on dead network
// after
client := &http.Client{Timeout: 30 * time.Second}
if err != nil {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
// retry with backoff
}
} Defensive patterns
Strategy: retry
Validate before calling
// preflight connectivity check
resp, err := http.Head("https://api.linear.app")
if err != nil {
return fmt.Errorf("linear unreachable: %w", err)
}
resp.Body.Close() Try / catch
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
// retry with backoff
}
if errors.Is(err, context.Canceled) {
// caller canceled; do not retry
} Prevention
- Set a sane HTTP client timeout (e.g. 30s) on the Linear client
- Implement exponential backoff retry for transient transport errors
- Check proxy/VPN/DNS health in deployment environments
- Distinguish context cancellation from real network failures before retrying
When it happens
Trigger: Network outage or DNS failure resolving api.linear.app; connection timeout because HTTPClient has no/short Timeout and Linear is slow or unreachable; ctx canceled while the request is in flight; TLS certificate errors (corporate proxy, wrong system clock); invalid proxy settings in the environment.
Common situations: CI runners without network egress; corporate proxy/VPN blocking api.linear.app; HTTP_CLIENT_TIMEOUT configured too aggressively; container DNS misconfiguration; server shutting down and canceling the context.
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
- server not reachable: %w
- git ls-remote %s failed: %s: %w
- max retries (%d) exceeded: %w
- oauth: token request failed: %w
- request failed: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/59cf98d61cc18573.
Report an issue: GitHub.