sigoden/aichat · error

Model ' ' is not a model

Error message

Model '{model_id}' is not a {model_type} model

What it means

`retrieve_model` (src/client/model.rs:66) bails when the requested model_id was found among the client's models, but its model_type differs from the requested model_type (e.g. asking for a chat model by the id of an embedding model). The model exists — it's just the wrong kind for the requested operation.

Solutions

  1. Use a model id whose configured type matches the requested operation, or request the correct ModelType for that id.
  2. Rename or re-add the model in config so it isn't auto-misclassified (avoid 'rank' in chat model names).
  3. Update the model entry in config to explicitly set the correct type.
  4. List configured models and their types before calling retrieve_model to pick the right id.

Example fix

// before
let m = retrieve_model(config, Some("text-embedding-3-small"), ModelType::Chat)?; // not a chat model
// after
let m = retrieve_model(config, Some("text-embedding-3-small"), ModelType::Embedding)?;
Defensive patterns

Strategy: type-guard

Validate before calling

// pick a model whose type matches the operation
let m = config.clients.iter()
    .flat_map(|c| c.models.iter())
    .find(|m| m.name == model_id && m.model_type == model_type);

Type guard

fn is_model_of_type(m: &Model, t: ModelType) -> bool { m.model_type() == t }

Try / catch

match retrieve_model(config, Some(id), ModelType::Chat, ...) {
    Err(e) if e.to_string().contains("is not a") => {
        // wrong type: retry with the model's actual type or a different id
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling retrieve_model(config, Some("my-embed-model"), ModelType::Chat, ...) (or equivalent for embedding/reranker) where the id matches a configured model of another type. Reranker names containing 'rank' or embedding names matching EMBEDDING_MODEL_RE are typed automatically during config.

Common situations: Model auto-typed as reranker because its name contains 'rank'; model name looks like an embedding model (e.g. 'text-embedding-...') so it was typed as embedding; user expects a chat model but config classified it differently.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/client/model.rs:66

    pub fn retrieve_model(config: &Config, model_id: &str, model_type: ModelType) -> Result<Self> {
        let models = list_all_models(config);
        let (client_name, model_name) = match model_id.split_once(':') {
            Some((client_name, model_name)) => {
                if model_name.is_empty() {
                    (client_name, None)
                } else {
                    (client_name, Some(model_name))
                }
            }
            None => (model_id, None),
        };
        match model_name {
            Some(model_name) => {
                if let Some(model) = models.iter().find(|v| v.id() == model_id) {
                    if model.model_type() == model_type {
                        return Ok((*model).clone());
                    } else {
                        bail!("Model '{model_id}' is not a {model_type} model")
                    }
                }
                if list_client_names(config)
                    .into_iter()
                    .any(|v| *v == client_name)
                    && model_type.can_create_from_name()
                {
                    let mut new_model = Self::new(client_name, model_name);
                    new_model.data.model_type = model_type.to_string();
                    return Ok(new_model);
                }
            }
            None => {
                if let Some(found) = models
                    .iter()
                    .find(|v| v.client_name == client_name && v.model_type() == model_type)
                {
                    return Ok((*found).clone());

View on GitHub (pinned to 82976d349a)