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