Hmbown/CodeWhale · error
Not a model preference key
Error message
Not a model preference key: {key} What it means
model_slot_for_document resolves which TOML slot (e.g. providers.<id>.model or default_text_model) a saved model preference lives in, for export. It rejects any key that is not a recognized route/model preference key (per is_route_key) or the 'provider' key, because 'provider' does not name a model slot. This is input validation to prevent writing/reading model data under an unknown config path.
Solutions
- Pass only keys accepted by is_route_key and not equal to "provider"
- Filter the key list through the same is_route_key predicate before calling
- Check the key spelling against the documented route keys (model, default_model, default_text_model, providers.<id>.model)
Example fix
// before
let slot = model_slot_for_document(&body, "provider")?;
// after
if is_route_key(key) && key != "provider" {
let slot = model_slot_for_document(&body, key)?;
} Defensive patterns
Strategy: validation
Validate before calling
if !is_route_key(key) || key == "provider" { return Err(anyhow!("skip: {key} is not a model preference key")); } Type guard
fn is_model_pref_key(key: &str) -> bool { is_route_key(key) && key != "provider" } Prevention
- Filter key lists through is_route_key before any route_preferences API
- Exclude "provider" when working with model slots
- Keep key names in a shared constant list instead of string literals
When it happens
Trigger: Calling model_slot_for_document(body, key) with key outside {model, default_model, default_text_model, providers.<id>.model} or with key == "provider"; e.g. passing "provider", a typo like "defaultmodel", or a device-preference key.
Common situations: Export/migration tooling iterating saved Settings keys; key spelling drift after renames; scripts forwarding arbitrary config keys without filtering to model keys.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- config entry must be a string
- active profile is missing or malformed
- agent profile provider cannot be empty
- agent profile provider must be a simple provider id
- api_key cannot be empty string
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/44a16b690a9f6cea.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/route_preferences.rs:88
return Ok(vec!["default_text_model"]);
}
let key = match identity.provider {
ApiProvider::Custom => identity.key.as_str(),
ApiProvider::DeepseekCN => "deepseek_cn",
ApiProvider::OllamaCloud if identity.migrated_legacy_ollama_cloud_route => "ollama",
provider => provider
.metadata()
.context("provider model table")?
.provider_config_key(),
};
Ok(vec!["providers", key, "model"])
}
/// Locate the canonical model leaf in a saved document without applying
/// device preferences or launch overrides. Export uses this same identity
/// resolution to omit only root aliases shadowed by that leaf.
pub fn model_slot_for_document(body: &str, key: &str) -> Result<Vec<String>> {
ensure!(
is_route_key(key) && key != "provider",
"Not a model preference key: {key}"
);
let config = parse_config(body)?;
let identity = model_identity(&config, key)?;
Ok(model_slot(&identity)?
.into_iter()
.map(str::to_string)
.collect())
}
fn document_slot_value(document: &toml::value::Table, slot: &[String]) -> Option<String> {
let [root, provider, field] = slot else {
return None;
};
document
.get(root)?
.as_table()?View on GitHub (pinned to 73e0f67d83)