{"record":{"id":"36a7995094b4b8ae","repo":"Kuberwastaken/claurst","slug":"bridge-poll-auth-error","errorCode":null,"errorMessage":"Bridge poll: auth error ({})","messagePattern":"Bridge poll: auth error \\((.+?)\\)","errorType":"http","errorClass":"anyhow::Error","httpStatus":401,"severity":"error","filePath":"src-rust/crates/bridge/src/lib.rs","lineNumber":580,"sourceCode":"            .send()\r\n            .await\r\n            .context(\"Bridge poll: HTTP send failed\")?;\r\n\r\n        let status = resp.status().as_u16();\r\n        match status {\r\n            200 => {\r\n                let text = resp.text().await.context(\"Bridge poll: reading body\")?;\r\n                if text.trim().is_empty() || text.trim() == \"[]\" {\r\n                    return Ok(vec![]);\r\n                }\r\n                let msgs: Vec<BridgeMessage> =\r\n                    serde_json::from_str(&text).context(\"Bridge poll: JSON parse\")?;\r\n                Ok(msgs)\r\n            }\r\n            204 => Ok(vec![]),\r\n            401 | 403 => {\r\n                self.set_state(BridgeState::Error(format!(\"Auth error: {status}\")));\r\n                anyhow::bail!(\"Bridge poll: auth error ({})\", status)\r\n            }\r\n            _ => {\r\n                anyhow::bail!(\"Bridge poll: server returned {}\", status)\r\n            }\r\n        }\r\n    }\r\n\r\n    // -----------------------------------------------------------------------\r\n    // Event upload\r\n    // -----------------------------------------------------------------------\r\n\r\n    /// Batch-upload outgoing events to the web UI.\r\n    ///\r\n    /// POST `/api/claude_code/sessions/{id}/events`\r\n    async fn upload_events(&self, events: Vec<BridgeEvent>) -> anyhow::Result<()> {\r\n        if events.is_empty() {\r\n            return Ok(());\r\n        }\r","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/bridge/src/lib.rs#L562-L598","documentation":"After a successful token-exchange HTTP response, `exchange_code` deserializes the body into its internal `TokenResponse` struct (access_token, refresh_token, expires_in, scope). If the body is not valid JSON or does not match the expected shape, the serde/reqwest error is wrapped as \"exchange_code: bad JSON: {}\". The token endpoint returned 2xx but not the JSON the library expects.","triggerScenarios":"`resp.json::<TokenResponse>()` fails — the endpoint returned HTML (e.g. an error page or login page behind a 200), an empty body, or JSON whose types differ (e.g. expires_in as string instead of u64).","commonSituations":"A reverse proxy or captive portal returning an HTML 200 page; the provider returning `application/x-www-form-urlencoded` instead of JSON for token responses; nonstandard field types (string \"3600\" for expires_in); token_endpoint pointing at the wrong URL.","solutions":["Capture and inspect the raw response body (curl the token endpoint with the same form payload) to see what was actually returned.","Verify the token_endpoint URL is correct and returns `application/json` for the authorization-code grant.","If behind a proxy/captive portal, fix the network path so the real provider response arrives.","If the provider uses nonstandard types, file/track support for that provider's wire format rather than re-running the flow."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// on \"exchange_code: bad JSON\", log the raw body to diagnose\nErr(e) if e.to_string().contains(\"bad JSON\") => {\n    eprintln!(\"Token endpoint returned non-JSON; verify token_endpoint and network path: {}\", e);\n    Err(e)\n}","preventionTips":["Curl the token endpoint with the same form payload to confirm it returns application/json","Ensure no captive portal/proxy injects HTML 200 responses","Confirm the token_endpoint from provider metadata is current"],"tags":["oauth","json","serde","http-response"],"backgroundTag":"invalid-json-response","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}