{"record":{"id":"e72a04e91b9ed41d","repo":"zeroclaw-labs/zeroclaw","slug":"channel-does-not-support-room-creation","errorCode":null,"errorMessage":"channel does not support room creation","messagePattern":"channel does not support room creation","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-api/src/channel.rs","lineNumber":904,"sourceCode":"\n    /// Unpin a previously pinned message.\n    async fn unpin_message(&self, _channel_id: &str, _message_id: &str) -> anyhow::Result<()> {\n        Ok(())\n    }\n\n    /// Redact (delete) a message from the channel.\n    async fn redact_message(\n        &self,\n        _channel_id: &str,\n        _message_id: &str,\n        _reason: Option<String>,\n    ) -> anyhow::Result<()> {\n        Ok(())\n    }\n\n    /// Create a new platform room/conversation when the channel supports it.\n    async fn create_room(&self, _options: &RoomCreationOptions) -> anyhow::Result<String> {\n        anyhow::bail!(\"channel does not support room creation\")\n    }\n\n    /// Invite a user to an existing platform room/conversation.\n    async fn invite_user(&self, _room_id: &str, _user_id: &str) -> anyhow::Result<()> {\n        anyhow::bail!(\"channel does not support room invites\")\n    }\n\n    /// Request interactive tool-call approval from the channel operator.\n    ///\n    /// Returns `Ok(Some(response))` when the operator answers within the\n    /// channel's configured `approval_timeout_secs`; timeouts surface as\n    /// `Deny`. Returns `Ok(None)` only for channels that do not implement\n    /// the prompt at all — the caller falls back to its default policy\n    /// (typically auto-deny).\n    async fn request_approval(\n        &self,\n        _recipient: &str,\n        _request: &ChannelApprovalRequest,","sourceCodeStart":886,"sourceCodeEnd":922,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-api/src/channel.rs#L886-L922","documentation":"check() (src/commands/update.rs:119) GETs the GitHub releases API — https://api.github.com/repos/zeroclaw-labs/zeroclaw/releases/latest, or /releases/tags/v<tag> when a --version is pinned — with an unauthenticated client (UA zeroclaw/<version>, 15s timeout) and bails on any non-2xx status, echoing the raw status. Reachability failures are a different error (\"failed to reach GitHub releases API\"); this one means GitHub answered but refused. Both `zeroclaw update` and update checks run through this function.","triggerScenarios":"`zeroclaw update [--check]` or `zeroclaw update --version <v>` when GitHub returns 403 (unauthenticated rate limit of 60 req/h per IP exceeded), 404 (pinned tag does not exist or no releases published), or a 5xx outage. Also triggered by any caller of update::check().","commonSituations":"Shared CI runner or NAT egress IP that exhausted the unauthenticated rate limit; typo'd or yanked --version tag; GitHub incident; proxies that answer with 4xx on behalf of GitHub.","solutions":["If 403: you hit the unauthenticated rate limit — wait for the window to reset and retry (curl -I the API URL and check x-ratelimit-reset)","If 404 with --version: verify the tag exists on the releases page; drop --version to fetch latest","Check https://www.githubstatus.com and your proxy/HTTPS_PROXY environment for 5xx or interception","Retry `zeroclaw update --check` after a minute — transient statuses clear on their own"],"exampleFix":"// before\nlet info = update::check(None).await?; // dies on first 403 rate-limit\n\n// after\nlet mut backoff = 30;\nlet info = loop {\n    match update::check(None).await {\n        Ok(i) => break i,\n        Err(e) if e.to_string().contains(\"GitHub API returned 403\") => {\n            tokio::time::sleep(std::time::Duration::from_secs(backoff)).await;\n            backoff *= 2;\n        }\n        Err(e) => return Err(e),\n    }\n};","handlingStrategy":"retry","validationCode":"// Cheap preflight: confirm the releases API answers 200 before running update.\nasync fn releases_api_ok() -> bool {\n    reqwest::Client::new()\n        .get(\"https://api.github.com/repos/zeroclaw-labs/zeroclaw/releases/latest\")\n        .header(\"User-Agent\", \"preflight\")\n        .send()\n        .await\n        .map(|r| r.status().is_success())\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match update::check(version).await {\n    Err(e) => {\n        let msg = e.to_string();\n        if msg.contains(\"403\") || msg.contains(\"429\") {\n            // Rate limited: sleep out the window (check x-ratelimit-reset), then retry once.\n        } else if msg.contains(\"404\") {\n            // Permanent: the pinned tag does not exist — fail fast with a clear message.\n        } else if msg.contains(\"5\") /* 5xx */ {\n            // Transient GitHub outage: retry with backoff.\n        }\n    }\n    ok => ok,\n}","preventionTips":["Do not poll the unauthenticated releases API in tight loops (60 req/h per IP)","Cache UpdateInfo results and re-check at most every few hours","Validate user-supplied --version tags against the releases page before invoking update"],"tags":["github-api","http-status","update","rate-limit","network"],"backgroundTag":"github-api-error-status","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}