{"record":{"id":"cc706f949587da97","repo":"sigoden/aichat","slug":"model-model-id-is-not-a-model-type-model","errorCode":null,"errorMessage":"Model '{model_id}' is not a {model_type} model","messagePattern":"Model '(.+?)' is not a (.+?) model","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/client/model.rs","lineNumber":66,"sourceCode":"    pub fn retrieve_model(config: &Config, model_id: &str, model_type: ModelType) -> Result<Self> {\n        let models = list_all_models(config);\n        let (client_name, model_name) = match model_id.split_once(':') {\n            Some((client_name, model_name)) => {\n                if model_name.is_empty() {\n                    (client_name, None)\n                } else {\n                    (client_name, Some(model_name))\n                }\n            }\n            None => (model_id, None),\n        };\n        match model_name {\n            Some(model_name) => {\n                if let Some(model) = models.iter().find(|v| v.id() == model_id) {\n                    if model.model_type() == model_type {\n                        return Ok((*model).clone());\n                    } else {\n                        bail!(\"Model '{model_id}' is not a {model_type} model\")\n                    }\n                }\n                if list_client_names(config)\n                    .into_iter()\n                    .any(|v| *v == client_name)\n                    && model_type.can_create_from_name()\n                {\n                    let mut new_model = Self::new(client_name, model_name);\n                    new_model.data.model_type = model_type.to_string();\n                    return Ok(new_model);\n                }\n            }\n            None => {\n                if let Some(found) = models\n                    .iter()\n                    .find(|v| v.client_name == client_name && v.model_type() == model_type)\n                {\n                    return Ok((*found).clone());","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/client/model.rs#L48-L84","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use a model id whose configured type matches the requested operation, or request the correct ModelType for that id.","Rename or re-add the model in config so it isn't auto-misclassified (avoid 'rank' in chat model names).","Update the model entry in config to explicitly set the correct type.","List configured models and their types before calling retrieve_model to pick the right id."],"exampleFix":"// before\nlet m = retrieve_model(config, Some(\"text-embedding-3-small\"), ModelType::Chat)?; // not a chat model\n// after\nlet m = retrieve_model(config, Some(\"text-embedding-3-small\"), ModelType::Embedding)?;","handlingStrategy":"type-guard","validationCode":"// pick a model whose type matches the operation\nlet m = config.clients.iter()\n    .flat_map(|c| c.models.iter())\n    .find(|m| m.name == model_id && m.model_type == model_type);","typeGuard":"fn is_model_of_type(m: &Model, t: ModelType) -> bool { m.model_type() == t }","tryCatchPattern":"match retrieve_model(config, Some(id), ModelType::Chat, ...) {\n    Err(e) if e.to_string().contains(\"is not a\") => {\n        // wrong type: retry with the model's actual type or a different id\n    }\n    other => other,\n}","preventionTips":["Avoid 'rank' substrings in chat model names (auto-typed as reranker).","Avoid embedding-style names for chat models (EMBEDDING_MODEL_RE match).","Set explicit model types in config instead of relying on auto-classification.","List models with types before choosing an id for an operation."],"tags":["model-type","type-mismatch","rust"],"backgroundTag":"type-mismatch","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"}