{"record":{"id":"ef7b32265f72560a","repo":"zeroclaw-labs/zeroclaw","slug":"live-model-listing-is-not-supported-for-this-model-ef7b32","errorCode":null,"errorMessage":"live model listing is not supported for this model_provider","messagePattern":"live model listing is not supported for this model_provider","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-providers/src/compatible.rs","lineNumber":2714,"sourceCode":"            })?;\n            return Ok(normalize_model_ids(body));\n        }\n        // No credential — try models.dev first, then OpenRouter as a\n        // last-resort fallback for vendors that aren't in models.dev.\n        if let Some(key) = &self.models_dev_key {\n            match crate::models_dev::list_models_for(key).await {\n                Ok(models) if !models.is_empty() => return Ok(models),\n                Ok(_) => {} // empty → fall through to openrouter\n                Err(e) => {\n                    if self.openrouter_vendor_prefix.is_none() {\n                        return Err(e);\n                    }\n                }\n            }\n        }\n        match &self.openrouter_vendor_prefix {\n            Some(prefix) => crate::openrouter_catalog::list_models_for_vendor(prefix).await,\n            None => anyhow::bail!(\"live model listing is not supported for this model_provider\"),\n        }\n    }\n\n    async fn list_models_with_pricing(\n        &self,\n    ) -> anyhow::Result<Vec<zeroclaw_api::model_provider::ModelInfo>> {\n        // When a credential is present, hit the provider's native /models\n        // endpoint — this returns pricing data that we can capture.\n        let list_credential = self.resolve_credential().await?;\n        if list_credential.is_some() || self.public_model_listing {\n            let url = format!(\"{}/models\", self.base_url);\n            let response = self\n                .apply_auth_header(self.http_client().get(&url), list_credential.as_deref())\n                .send()\n                .await\n                .map_err(|e| {\n                    ::zeroclaw_log::record!(\n                        ERROR,","sourceCodeStart":2696,"sourceCodeEnd":2732,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-providers/src/compatible.rs#L2696-L2732","documentation":"list_models on an OpenAI-compatible provider can enumerate models only when it has at least one source: a resolved credential (native /models), public_model_listing, a models_dev key, or an openrouter_vendor_prefix. With none of these configured there is no way to list models live, so it bails rather than return an empty list that would look like 'no models exist'.","triggerScenarios":"Calling list_models() on a compatible-family alias configured without api_key, without public_model_listing = true, without models_dev_key, and without openrouter_vendor_prefix - typically a bare custom alias meant for chat only.","commonSituations":"Local aliases with a hardcoded default model and no credential in config; UI model pickers that call list_models on every alias; setups where the key is supplied per-request instead of in configuration.","solutions":["Set an api_key on the alias so the native {base_url}/models endpoint is used","Set public_model_listing = true for local servers that expose /models without authentication","Set models_dev_key (or openrouter_vendor_prefix for vendors listed on OpenRouter) so a public catalog is used","Or configure the alias's static models list and skip live listing for it"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Only call live listing when the alias can actually support it\nlet can_list = alias.api_key.is_some()\n    || alias.public_model_listing\n    || alias.models_dev_key.is_some()\n    || alias.openrouter_vendor_prefix.is_some();\nif !can_list {\n    return Ok(alias.static_models.clone()); // skip live listing entirely\n}","typeGuard":null,"tryCatchPattern":"match provider.list_models().await {\n    Ok(models) => Ok(models),\n    Err(e) if e.to_string().contains(\"live model listing is not supported\") => {\n        Ok(alias.static_models.clone()) // known limitation: use configured list\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Mark aliases as chat-only and give them a static models list in config","Do not auto-call list_models on every configured alias from UI code","Enable public_model_listing for keyless local servers","Document per alias whether live listing is expected to work"],"tags":["openai-compatible","models","capabilities","config","rust"],"backgroundTag":"unsupported-operation","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}