{"record":{"id":"f3e9047916c407d1","repo":"zeroclaw-labs/zeroclaw","slug":"failed-to-list-telnyx-models","errorCode":null,"errorMessage":"Failed to list Telnyx models: {}","messagePattern":"Failed to list Telnyx models: (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-providers/src/telnyx.rs","lineNumber":84,"sourceCode":"                ERROR,\n                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Reject)\n                    .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                    .with_attrs(::serde_json::json!({\"missing\": \"api_key\"})),\n                \"telnyx: API key not configured\"\n            );\n            anyhow::Error::msg(\"Telnyx API key not set. Set TELNYX_API_KEY environment variable.\")\n        })?;\n\n        let response = self\n            .client\n            .get(format!(\"{}/models\", BASE_URL))\n            .header(\"Authorization\", format!(\"Bearer {}\", api_key))\n            .send()\n            .await?;\n\n        if !response.status().is_success() {\n            let error = response.text().await?;\n            anyhow::bail!(\"Failed to list Telnyx models: {}\", error);\n        }\n\n        let models_response: ModelsResponse = response.json().await?;\n        Ok(models_response.data.into_iter().map(|m| m.id).collect())\n    }\n\n    /// Build the chat completions URL\n    fn chat_url(&self) -> String {\n        format!(\"{}/chat/completions\", BASE_URL)\n    }\n}\n\nfn resolve_telnyx_api_key(api_key: Option<&str>) -> Option<String> {\n    api_key\n        .map(str::trim)\n        .filter(|k| !k.is_empty())\n        .map(ToString::to_string)\n}","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-providers/src/telnyx.rs#L66-L102","documentation":"The Telnyx provider's list_models issued its GET against the Telnyx AI models endpoint and got a non-success HTTP status; the raw response body is embedded in the error (this path does not run sanitize_api_error). Typical causes are authentication failures or a wrong base URL rather than transient network issues.","triggerScenarios":"Invalid or expired Telnyx API key yields 401 with the API's error body; account without AI API access; base_url misconfigured so the models path lands on the wrong Telnyx product; Telnyx-side 5xx.","commonSituations":"TELNYX_API_KEY unset or stale in the environment; a key provisioned for Voice/Messaging only; copy-pasting another provider's base_url into the telnyx provider entry.","solutions":["Curl the models endpoint with the same key and inspect the status and body to confirm the failure.","Verify the API key is set, current, and has AI API scope in the Telnyx console.","Check the telnyx provider's base_url matches Telnyx's AI inference endpoint.","For 5xx bodies, retry later — nothing in the client config will fix a provider outage."],"exampleFix":"# before — key from another product, no AI scope\nexport TELNYX_API_KEY=\"KEYxxxxxxxx voice-only\"\n\n# after — key created with AI API access in the Telnyx console\nexport TELNYX_API_KEY=\"KEYxxxxxxxx-with-ai-scope\"","handlingStrategy":"try-catch","validationCode":"# Verify key + endpoint before the first programmatic call\ncurl -s -o /dev/null -w '%{http_code}' \\\n  -H \"Authorization: Bearer $TELNYX_API_KEY\" \\\n  \"$TELNYX_BASE_URL/models\"   # expect 200","typeGuard":null,"tryCatchPattern":"Catch the error, curl the same endpoint with the same key to confirm, then branch: 401/403 → fix credentials (do not retry), 5xx → retry later with backoff. The body in the message is the API's own error text — surface it.","preventionTips":["Create the key with AI API scope in the Telnyx console, not a Voice/Messaging key","Smoke-test the models endpoint in CI with the real secret","Alert on repeated list_models failures to catch key expiry early"],"tags":["telnyx","http-status","llm-provider","authentication","network"],"backgroundTag":"llm-api-http-error","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}