{"record":{"id":"4840beb6d952e85a","repo":"Kuberwastaken/claurst","slug":"models-endpoint-returned","errorCode":null,"errorMessage":"models endpoint returned {}","messagePattern":"models endpoint returned (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-rust/crates/api/src/lib.rs","lineNumber":915,"sourceCode":"                req = req\r\n                    .header(\r\n                        \"anthropic-beta\",\r\n                        claurst_core::oauth_config::OAUTH_BETA_FLAGS.join(\",\"),\r\n                    )\r\n                    .header(\r\n                        \"user-agent\",\r\n                        claurst_core::oauth_config::claude_code_user_agent(),\r\n                    )\r\n                    .header(\"x-app\", \"cli\")\r\n                    .header(\"Authorization\", format!(\"Bearer {}\", self.config.api_key));\r\n            } else {\r\n                req = req.header(\"x-api-key\", &self.config.api_key);\r\n            }\r\n\r\n            let resp = req.send().await?;\r\n\r\n            if !resp.status().is_success() {\r\n                anyhow::bail!(\"models endpoint returned {}\", resp.status());\r\n            }\r\n\r\n            #[derive(serde::Deserialize)]\r\n            struct ModelsResponse {\r\n                data: Vec<crate::AvailableModel>,\r\n            }\r\n\r\n            let body: ModelsResponse = resp.json().await?;\r\n            Ok(body.data)\r\n        }\r\n\r\n        // ---- Internal helpers --------------------------------------------\r\n\r\n        /// Build the common request and execute with retry logic.\r\n        async fn send_with_retry(\r\n            &self,\r\n            body: &Value,\r\n        ) -> Result<wreq::Response, ClaudeError> {\r","sourceCodeStart":897,"sourceCodeEnd":933,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/api/src/lib.rs#L897-L933","documentation":"In `wait_for_authorization_code` (src-rust/crates/mcp/src/oauth.rs:275), after the MCP OAuth callback request arrives on the local listener, the server writes a fixed HTTP 200 response back to the browser before reading the redirect target. If `write_all` on the TCP stream fails, this anyhow error wraps the underlying io::Error. It means the local HTTP handshake with the browser could not complete.","triggerScenarios":"The TCP writer to the browser (or HTTP client) errors during `writer.write_all(response.as_bytes()).await` after a callback request was accepted — e.g. the client closed the connection before the response was written, or the OS socket failed.","commonSituations":"User closes the browser tab (or presses Escape / navigates away) the instant the redirect lands, so the socket is already closed; a browser or proxy that aborts the connection early; system-level socket exhaustion; firewall/AV software resetting local loopback connections.","solutions":["Re-run the auth flow and leave the browser tab open until it shows 'MCP OAuth authentication finished. You can close this tab.'","Retry `run_mcp_auth_flow`; the error is transient when caused by a premature tab close.","Check that local loopback connections are not intercepted/reset by firewall, proxy, or antivirus software.","If it reproduces consistently, verify the listener is still alive (no port hijack) and inspect the wrapped io::Error message for the root cause."],"exampleFix":"// before: auth flow errors out when the user closes the tab too fast\n// after: caller retries or tolerates the write failure by re-running the session\nmatch run_mcp_auth_flow(&session).await {\n    Ok(result) => result,\n    Err(e) if e.to_string().contains(\"Failed to write OAuth callback response\") => {\n        eprintln!(\"Browser closed too early, retrying...\");\n        run_mcp_auth_flow(&session).await?\n    }\n    Err(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match run_mcp_auth_flow(&session).await {\n    Ok(r) => r,\n    Err(e) if e.to_string().contains(\"Failed to write OAuth callback response\") => {\n        // transient: user closed the tab; retry the whole flow\n        run_mcp_auth_flow(&session).await?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Instruct users to keep the browser tab open until the confirmation page appears","Avoid proxies/AV that intercept loopback traffic during auth","Treat this error as retryable and automate one retry"],"tags":["oauth","network","io","async"],"backgroundTag":"broken-pipe","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"}