{"record":{"id":"dfd2fd3be610ea25","repo":"gastownhall/beads","slug":"oauth-failed-to-parse-token-response-w","errorCode":null,"errorMessage":"oauth: failed to parse token response: %w","messagePattern":"oauth: failed to parse token response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/oauth.go","lineNumber":150,"sourceCode":"\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tbody, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) // 1MB limit\n\tif err != nil {\n\t\treturn fmt.Errorf(\"oauth: failed to read token response: %w\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tvar errResp oauthErrorResponse\n\t\tif json.Unmarshal(body, &errResp) == nil && errResp.Error != \"\" {\n\t\t\treturn fmt.Errorf(\"oauth: token request failed (%s): %s\", errResp.Error, errResp.Description)\n\t\t}\n\t\treturn fmt.Errorf(\"oauth: token request returned status %d: %s\", resp.StatusCode, string(body))\n\t}\n\n\tvar tokenResp oauthTokenResponse\n\tif err := json.Unmarshal(body, &tokenResp); err != nil {\n\t\treturn fmt.Errorf(\"oauth: failed to parse token response: %w\", err)\n\t}\n\n\tif tokenResp.AccessToken == \"\" {\n\t\treturn fmt.Errorf(\"oauth: token response missing access_token\")\n\t}\n\n\tm.token = tokenResp.AccessToken\n\tm.expiresAt = m.nowFunc().Add(time.Duration(tokenResp.ExpiresIn) * time.Second)\n\n\tdebug.Logf(\"oauth: acquired token (expires in %ds)\", tokenResp.ExpiresIn)\n\treturn nil\n}\n","sourceCodeStart":132,"sourceCodeEnd":163,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/oauth.go#L132-L163","documentation":"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.","triggerScenarios":"json.Unmarshal(body, &tokenResp) fails in acquireToken after a 200 response — e.g. body is HTML, empty, or a different JSON shape.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"failed to parse token response\") {\n    // log/redact raw body and verify TokenURL returns JSON\n}","preventionTips":["Confirm the endpoint returns application/json with a smoke test.","Bypass or fix content-rewriting proxies.","Log (sanitized) response content-type on failure."],"tags":["oauth","json","response-parsing","go"],"backgroundTag":"token-response-parse-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}