{"record":{"id":"e5cbd48dbfb99ad6","repo":"sigoden/aichat","slug":"invalid-model","errorCode":null,"errorMessage":"Invalid model '{}'","messagePattern":"Invalid model '(.+?)'","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/client/macros.rs","lineNumber":80,"sourceCode":"                        vec![]\n                    } else {\n                        Model::from_config(client_name, &local_config.models)\n                    }\n                }\n\n                pub fn name(local_config: &$config) -> &str {\n                    local_config.name.as_deref().unwrap_or(Self::NAME)\n                }\n            }\n\n        )+\n\n        pub fn init_client(config: &$crate::config::GlobalConfig, model: Option<$crate::client::Model>) -> anyhow::Result<Box<dyn Client>> {\n            let model = model.unwrap_or_else(|| config.read().model.clone());\n            None\n            $(.or_else(|| $client::init(config, &model)))+\n            .ok_or_else(|| {\n                anyhow::anyhow!(\"Invalid model '{}'\", model.id())\n            })\n        }\n\n        pub fn list_client_types() -> Vec<&'static str> {\n            let mut client_types: Vec<_> = vec![$($client::NAME,)+];\n            client_types.extend($crate::client::OPENAI_COMPATIBLE_PROVIDERS.iter().map(|(name, _)| *name));\n            client_types\n        }\n\n        pub async fn create_client_config(client: &str) -> anyhow::Result<(String, serde_json::Value)> {\n            $(\n                if client == $client::NAME && client != $crate::client::OpenAICompatibleClient::NAME {\n                    return create_config(&$client::PROMPTS, $client::NAME).await\n                }\n            )+\n            if let Some(ret) = create_openai_compatible_client_config(client).await? {\n                return Ok(ret);\n            }","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/client/macros.rs#L62-L98","documentation":"Generated by the client registration macro, init_client tries each registered client's init() against the requested model and, if none accepts it, fails with 'Invalid model <model.id()>'. The model id must map to a known provider/client (e.g. prefix like 'openai:gpt-4').","triggerScenarios":"Calling init_client (or CLI commands taking --model) with a model id whose provider prefix doesn't match any registered client or OpenAI-compatible provider; typo'd provider name; missing provider env config so its init() returns None.","commonSituations":"Misspelled provider in MODEL (e.g. 'opneai:gpt-4o'); provider not compiled/registered in this build; using a model id without the required provider prefix; an OpenAI-compatible provider requiring extra config (api_base/key) that wasn't provided.","solutions":["Check the model id format provider:model (run the list-clients/models command to see valid prefixes)","Fix typos in the provider prefix","Add the required provider configuration (API key / api_base) so the client's init succeeds","Use a model offered by a registered client, or register/configure the desired OpenAI-compatible provider"],"exampleFix":"// before\nlet client = init_client(&config, Some(Model::new(\"gpt-4o\")))?; // no provider prefix\n// after\nlet client = init_client(&config, Some(Model::new(\"openai:gpt-4o\")))?;","handlingStrategy":"validation","validationCode":"// validate the model id has a known provider prefix before init\nlet valid_prefixes = list_client_types();\nlet prefix_ok = model.id().split_once(':')\n    .map(|(p, _)| valid_prefixes.contains(&p))\n    .unwrap_or(false);\nif !prefix_ok { /* correct MODEL / --model before init */ }","typeGuard":"fn has_known_provider(model_id: &str, known: &[&str]) -> bool {\n    model_id.split_once(':').map_or(false, |(p, _)| known.contains(&p))\n}","tryCatchPattern":"match init_client(&config, model) {\n    Ok(client) => client,\n    Err(e) if e.to_string().starts_with(\"Invalid model\") => {\n        eprintln!(\"{e}; run `aichat --list-models` for valid ids\");\n        std::process::exit(2);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always use provider-prefixed model ids like openai:gpt-4o","Verify the provider is registered in this build and its env/config (key, api_base) is present","Validate MODEL in config against the output of the list-models command","Watch for typos in provider prefixes when editing config files"],"tags":["model","config","cli","provider"],"backgroundTag":"invalid-argument-value","analyzedSha":"82976d349ad97ac9aae0655ad631dace5e2a6385","analyzedAt":"2026-09-09T18:33:06.139Z","contentChangedAt":"2026-09-09T18:33:06.139Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}