{"record":{"id":"a514df14015bfd58","repo":"Kuberwastaken/claurst","slug":"upload-no-token","errorCode":null,"errorMessage":"Upload: no token","messagePattern":"Upload: no token","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-rust/crates/bridge/src/lib.rs","lineNumber":604,"sourceCode":"    }\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\n\r\n        let token = self\r\n            .config\r\n            .session_token\r\n            .as_deref()\r\n            .ok_or_else(|| anyhow::anyhow!(\"Upload: no token\"))?;\r\n\r\n        let url = format!(\r\n            \"{}/api/claude_code/sessions/{}/events\",\r\n            self.config.server_url, self.session_id\r\n        );\r\n\r\n        let body = serde_json::json!({ \"events\": events });\r\n\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","sourceCodeStart":586,"sourceCodeEnd":622,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/bridge/src/lib.rs#L586-L622","documentation":"`upload_events` posts pending bridge events to the server and requires the session token for authentication. If `config.session_token` is `None`, the upload fails with this error. This surfaces in the poll loop (`run_poll_loop`) when event uploads run without credentials.","triggerScenarios":"`upload_events` called from `run_poll_loop` while `self.config.session_token` is `None` — bridge configured without a token or token cleared post-registration.","commonSituations":"Same root cause as 'Poll: no token': a BridgeConfig lacking session_token reaching the event-upload stage; unit tests driving the loop with a minimal config.","solutions":["Provide `session_token` in the BridgeConfig before entering `run_poll_loop`.","Use the standard start path (`start_bridge_with_client` / token resolution at lib.rs:938) which validates the token up front.","Buffer events locally and retry the upload after the token is restored, instead of dropping them."],"exampleFix":"// before\nlet config = BridgeConfig { server_url, session_token: None, .. };\nbridge.upload_events(&events).await?; // Upload: no token\n// after\nlet config = BridgeConfig {\n    server_url,\n    session_token: Some(token), // from CLAURST_BRIDGE_TOKEN\n    ..Default::default()\n};","handlingStrategy":"validation","validationCode":"// Ensure credentials exist before entering run_poll_loop\nif bridge.config.session_token.is_none() {\n    anyhow::bail!(\"run_poll_loop requires a session token\");\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = bridge.upload_events(&events).await {\n    if e.to_string().contains(\"no token\") {\n        // buffer events and re-authenticate before retrying\n        pending_events.extend(events);\n    }\n}","preventionTips":["Use the same startup validation for token presence that the register path enforces.","Buffer outbound events so a token gap doesn't lose telemetry.","Treat token absence as fatal at loop start, not per-iteration."],"tags":["bridge","authentication","remote-control","missing-token"],"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"}