Hmbown/CodeWhale · error
Not a route preference key
Error message
Not a route preference key: {key} What it means
get reads the saved route preference for a key without applying launch overrides or credentials. It first validates the key with is_route_key and rejects anything that is not a provider or model selection key. This keeps reads from silently returning data for unknown or device-specific keys.
Solutions
- Use a valid route key: provider, model, default_model, default_text_model, or providers.<id>.model
- Validate with is_route_key(key) before calling get
- Correct the key spelling
Example fix
// before let v = get(&path, "model_provider")?; // after let v = get(&path, "provider")?;
Defensive patterns
Strategy: validation
Validate before calling
if !is_route_key(key) { return Err(anyhow!("{key} is not a route preference key")); } Type guard
fn is_route_key(key: &str) -> bool {
matches!(key, "provider"|"model"|"default_model"|"default_text_model")
|| key.strip_prefix("providers.").and_then(|r| r.strip_suffix(".model")).is_some_and(|id| !id.is_empty())
} Try / catch
match get(&path, key) {
Ok(v) => v,
Err(e) if e.to_string().contains("Not a route preference key") => { eprintln!("use provider|model|default_model|default_text_model|providers.<id>.model"); None }
Err(e) => return Err(e),
} Prevention
- Use is_route_key as a pre-check
- Centralize route key names in constants
- Avoid forwarding arbitrary config keys to route APIs
When it happens
Trigger: Calling route_preferences::get(path, key) with key not in {provider, model, default_model, default_text_model, providers.<id>.model}; e.g. typos like "models" or arbitrary config keys.
Common situations: Scripts querying route state with mistyped key names; callers assuming any config key is readable through this API.
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
- agent profile provider cannot be empty
- agent profile provider must be a simple provider id
- api_key cannot be empty string
- approval_policy ' ' is not allowed by requirements ( )
- budget document_kind must be
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/e0392d95b3089e79.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/route_preferences.rs:286
original
} else {
rendered = store.rendered_body()?;
&rendered
};
let mut config = parse_config(body)?;
if config.route_preferences_version.is_none()
&& crate::config::is_home_config_path(store.path())
{
config.apply_saved_selection(
&crate::settings::Settings::load_legacy_route_preferences_read_only()?,
);
}
Ok(config)
}
/// Read the saved route without applying launch overrides or credentials.
pub fn get(path: &Path, key: &str) -> Result<Option<String>> {
ensure!(is_route_key(key), "Not a route preference key: {key}");
let store = codewhale_config::ConfigStore::load(Some(path.to_path_buf()))?;
if let Some(key) = project_root_key(store.path(), key) {
return Ok(store.config.get_value(key));
}
let mut config = saved_config(&store)?;
if key == "provider" {
return Ok(Some(
config.provider.unwrap_or_else(|| "deepseek".to_string()),
));
}
let identity = model_identity(&config, key)?;
config.scope_to_provider_identity(&identity);
Ok(config
.provider_config_for(identity.provider)
.and_then(|entry| entry.model.clone())
.or_else(|| {
(provider_model_id(key).is_none()
&& (config.default_text_model.is_some() || config.legacy_model.is_some()))View on GitHub (pinned to 73e0f67d83)