sigoden/aichat · error · anyhow::Error

Invalid model

Error message

Invalid model '{}'

What it means

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').

Solutions

  1. Check the model id format provider:model (run the list-clients/models command to see valid prefixes)
  2. Fix typos in the provider prefix
  3. Add the required provider configuration (API key / api_base) so the client's init succeeds
  4. Use a model offered by a registered client, or register/configure the desired OpenAI-compatible provider

Example fix

// before
let client = init_client(&config, Some(Model::new("gpt-4o")))?; // no provider prefix
// after
let client = init_client(&config, Some(Model::new("openai:gpt-4o")))?;
Defensive patterns

Strategy: validation

Validate before calling

// validate the model id has a known provider prefix before init
let valid_prefixes = list_client_types();
let prefix_ok = model.id().split_once(':')
    .map(|(p, _)| valid_prefixes.contains(&p))
    .unwrap_or(false);
if !prefix_ok { /* correct MODEL / --model before init */ }

Type guard

fn has_known_provider(model_id: &str, known: &[&str]) -> bool {
    model_id.split_once(':').map_or(false, |(p, _)| known.contains(&p))
}

Try / catch

match init_client(&config, model) {
    Ok(client) => client,
    Err(e) if e.to_string().starts_with("Invalid model") => {
        eprintln!("{e}; run `aichat --list-models` for valid ids");
        std::process::exit(2);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/e5cbd48dbfb99ad6. Report an issue: GitHub.

Appendix: source

Thrown at src/client/macros.rs:80

                        vec![]
                    } else {
                        Model::from_config(client_name, &local_config.models)
                    }
                }

                pub fn name(local_config: &$config) -> &str {
                    local_config.name.as_deref().unwrap_or(Self::NAME)
                }
            }

        )+

        pub fn init_client(config: &$crate::config::GlobalConfig, model: Option<$crate::client::Model>) -> anyhow::Result<Box<dyn Client>> {
            let model = model.unwrap_or_else(|| config.read().model.clone());
            None
            $(.or_else(|| $client::init(config, &model)))+
            .ok_or_else(|| {
                anyhow::anyhow!("Invalid model '{}'", model.id())
            })
        }

        pub fn list_client_types() -> Vec<&'static str> {
            let mut client_types: Vec<_> = vec![$($client::NAME,)+];
            client_types.extend($crate::client::OPENAI_COMPATIBLE_PROVIDERS.iter().map(|(name, _)| *name));
            client_types
        }

        pub async fn create_client_config(client: &str) -> anyhow::Result<(String, serde_json::Value)> {
            $(
                if client == $client::NAME && client != $crate::client::OpenAICompatibleClient::NAME {
                    return create_config(&$client::PROMPTS, $client::NAME).await
                }
            )+
            if let Some(ret) = create_openai_compatible_client_config(client).await? {
                return Ok(ret);
            }

View on GitHub (pinned to 82976d349a)