gastownhall/beads · error
oauth: failed to parse token response: %w
Error message
oauth: failed to parse token response: %w
What it means
The token endpoint returned HTTP 200 but the body could not be parsed as the expected token JSON (oauthTokenResponse). The server responded with something other than a well-formed access-token payload.
Source
Thrown at internal/linear/oauth.go:150
}
defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) // 1MB limit
if err != nil {
return fmt.Errorf("oauth: failed to read token response: %w", err)
}
if resp.StatusCode != http.StatusOK {
var errResp oauthErrorResponse
if json.Unmarshal(body, &errResp) == nil && errResp.Error != "" {
return fmt.Errorf("oauth: token request failed (%s): %s", errResp.Error, errResp.Description)
}
return fmt.Errorf("oauth: token request returned status %d: %s", resp.StatusCode, string(body))
}
var tokenResp oauthTokenResponse
if err := json.Unmarshal(body, &tokenResp); err != nil {
return fmt.Errorf("oauth: failed to parse token response: %w", err)
}
if tokenResp.AccessToken == "" {
return fmt.Errorf("oauth: token response missing access_token")
}
m.token = tokenResp.AccessToken
m.expiresAt = m.nowFunc().Add(time.Duration(tokenResp.ExpiresIn) * time.Second)
debug.Logf("oauth: acquired token (expires in %ds)", tokenResp.ExpiresIn)
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Dump (redacted) response body to confirm what the endpoint actually returned.
- Correct the TokenURL if it resolves to an HTML page with 200.
- Confirm the request's Accept/Content-Type headers are application/x-www-form-urlencoded as set by the client.
- Check whether a corporate proxy is rewriting the response.
Defensive patterns
Strategy: try-catch
Try / catch
if strings.Contains(err.Error(), "failed to parse token response") {
// log/redact raw body and verify TokenURL returns JSON
} Prevention
- Confirm the endpoint returns application/json with a smoke test.
- Bypass or fix content-rewriting proxies.
- Log (sanitized) response content-type on failure.
When it happens
Trigger: json.Unmarshal(body, &tokenResp) fails in acquireToken after a 200 response — e.g. body is HTML, empty, or a different JSON shape.
Common situations: TokenURL pointing at a page that returns 200 HTML; a proxy injecting content; provider changed response format (unlikely); content-type negotiation returning form-encoded data.
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
- ExternalDoltConfig: must set Socket or (Host, Port)
- failed to parse backup state: %w
- failed to marshal backup state: %w
- failed to marshal issue %s: %w
- failed to load config: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/dfd2fd3be610ea25.
Report an issue: GitHub.