{"record":{"id":"fb3c755873e13072","repo":"Kuberwastaken/claurst","slug":"bridge-upload-server-returned","errorCode":null,"errorMessage":"Bridge upload: server returned {}","messagePattern":"Bridge upload: server returned (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-rust/crates/bridge/src/lib.rs","lineNumber":630,"sourceCode":"\r\n        let resp = self\r\n            .http\r\n            .post(&url)\r\n            .bearer_auth(token)\r\n            .json(&body)\r\n            .send()\r\n            .await\r\n            .context(\"Bridge upload: HTTP send failed\")?;\r\n\r\n        if !resp.status().is_success() {\r\n            let status = resp.status().as_u16();\r\n            warn!(\r\n                session_id = %self.session_id,\r\n                status,\r\n                count = events.len(),\r\n                \"Bridge event upload failed\"\r\n            );\r\n            anyhow::bail!(\"Bridge upload: server returned {}\", status);\r\n        }\r\n\r\n        debug!(\r\n            session_id = %self.session_id,\r\n            count = events.len(),\r\n            \"Bridge events uploaded\"\r\n        );\r\n        Ok(())\r\n    }\r\n\r\n    // -----------------------------------------------------------------------\r\n    // Main poll loop\r\n    // -----------------------------------------------------------------------\r\n\r\n    /// Run the bridge poll loop until `cancel` is triggered or a fatal error\r\n    /// occurs.\r\n    ///\r\n    /// On each iteration:\r","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/bridge/src/lib.rs#L612-L648","documentation":"Within `refresh_mcp_token`, after loading the stored token, the code reads `existing.refresh_token`. If the stored `McpToken` has no refresh token (the provider did not issue one during the original exchange), this error is returned. Without a refresh token the library cannot silently renew the credentials.","triggerScenarios":"The stored token for `server_name` exists but `refresh_token` is None — the original authorization/token exchange did not yield a refresh token, and now `get_valid_mcp_token` attempts a refresh.","commonSituations":"Provider that only issues refresh tokens with specific scopes (e.g. Google requires offline access) or for certain client types; the original flow stored a short-lived token without a refresh grant; older stored tokens created before refresh support was added.","solutions":["Re-run `run_mcp_auth_flow` to obtain a fresh token that includes a refresh token.","Check the provider's requirements: request the scopes needed for refresh tokens (e.g. offline_access) in the authorization URL.","Verify the token exchange actually returns a refresh_token field for this provider/client.","Until re-auth, treat the token as non-renewable: re-authenticate each time it expires."],"exampleFix":"// before: auth_url scopes may omit refresh-eligible scope\n// after: include offline access so a refresh token is issued\nlet auth_url = format!(\n    \"{}?response_type=code&client_id={}&redirect_uri={}&scope={} offline_access&state={}\",\n    auth_endpoint, client_id, redirect_uri, scopes, state\n);","handlingStrategy":"fallback","validationCode":"// before refreshing, check a refresh token is available\nlet can_refresh = get_mcp_token(server_name)\n    .and_then(|t| t.refresh_token)\n    .is_some();","typeGuard":null,"tryCatchPattern":"match refresh_mcp_token(server, endpoint).await {\n    Ok(t) => t,\n    Err(e) if e.to_string().contains(\"has no refresh token\") => {\n        run_mcp_auth_flow(&session).await? // re-auth required\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Request offline_access (or the provider's refresh-eligible scope) in the authorization URL","Re-authenticate after migrating tokens from versions that did not store refresh tokens","Verify the provider issues refresh tokens for your client type"],"tags":["oauth","refresh-token","token-store"],"backgroundTag":"missing-credentials","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"}