{"record":{"id":"666785f7a2bc963d","repo":"zeroclaw-labs/zeroclaw","slug":"failed-to-fetch-bot-info","errorCode":null,"errorMessage":"Failed to fetch bot info: {}","messagePattern":"Failed to fetch bot info: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/telegram.rs","lineNumber":1533,"sourceCode":"    async fn classify_edit_message_response(resp: reqwest::Response) -> EditMessageResult {\n        if resp.status().is_success() {\n            return EditMessageResult::Success;\n        }\n\n        let status = resp.status();\n        let body = resp.text().await.unwrap_or_default();\n        if body.contains(\"message is not modified\") {\n            return EditMessageResult::NotModified;\n        }\n\n        EditMessageResult::Failed(status)\n    }\n\n    async fn fetch_bot_username(&self) -> anyhow::Result<String> {\n        let resp = self.http_client().get(self.api_url(\"getMe\")).send().await?;\n\n        if !resp.status().is_success() {\n            anyhow::bail!(\"Failed to fetch bot info: {}\", resp.status());\n        }\n\n        let data: serde_json::Value = resp.json().await?;\n        let result = data\n            .get(\"result\")\n            .context(\"missing result in getMe response\")?;\n        let username = result\n            .get(\"username\")\n            .and_then(|u| u.as_str())\n            .context(\"Bot username not found in response\")?;\n\n        // Cache the bot's user ID for reply-to-self detection\n        if let Some(id) = result.get(\"id\").and_then(|i| i.as_i64()) {\n            let mut cache = self.bot_id.lock();\n            *cache = Some(id);\n        }\n\n        Ok(username.to_string())","sourceCodeStart":1515,"sourceCodeEnd":1551,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/telegram.rs#L1515-L1551","documentation":"fetch_bot_username() GETs the Bot API `getMe` endpoint (during startup/pairing to learn the bot's @username) and bails with the raw HTTP status on any non-2xx. It is usually the first authenticated call against the Bot API, so a failure almost always means the bot_token or api_base is wrong before anything else runs.","triggerScenarios":"401 Unauthorized with an invalid or revoked bot_token; 404 from a custom api_base pointing at a local telegram-bot-api-server that is not running or has the wrong path; an intermediate proxy returning an error page status.","commonSituations":"Token regenerated with @BotFather after the old one was revoked; copy-paste typo in the token; api_base override for a self-hosted Bot API server misconfigured; captive portals or corporate proxies intercepting the request.","solutions":["Verify the token directly: `curl https://api.telegram.org/bot<TOKEN>/getMe` must return \"ok\":true.","If api_base is overridden for a local Bot API server, confirm the server is up and the base URL/path is correct.","Re-issue the token via @BotFather and update it with `zeroclaw config set channels.telegram.<alias>.bot_token <new-token>`.","Restart the channel/process after fixing credentials."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// preflight the credentials before wiring the channel\nlet resp = reqwest::get(format!(\"{api_base}/bot{token}/getMe\")).await?;\nanyhow::ensure!(resp.status().is_success(), \"bot token rejected: {}\", resp.status());","typeGuard":"fn is_auth_failure(err: &anyhow::Error) -> bool {\n    err.to_string().contains(\"Failed to fetch bot info: 401\")\n}","tryCatchPattern":"if let Err(e) = channel.fetch_bot_username().await {\n    if is_auth_failure(&e) {\n        anyhow::bail!(\"bot_token invalid or revoked; reissue with @BotFather and update config\");\n    }\n    return Err(e);\n}","preventionTips":["Run a getMe preflight during channel startup so bad tokens fail before polling begins.","After regenerating a token with @BotFather, update config immediately and restart.","For self-hosted Bot API servers, health-check api_base before startup."],"tags":["telegram","getme","auth","bot-token","startup"],"backgroundTag":"telegram-bot-api-error","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}