Hmbown/CodeWhale · error
Could not read legacy route preferences; configuration was…
Error message
Could not read legacy route preferences; configuration was not changed
What it means
After parsing the config, migrate_legacy_route_preferences loads the legacy settings.toml to read saved route preferences. If Settings::load_legacy_route_preferences_read_only fails, it refuses with this error, leaving the configuration untouched, because proceeding would migrate from nothing.
Solutions
- Ensure the legacy settings.toml exists and is readable by the current user
- Fix file permissions on the settings file (chmod/chown as appropriate)
- If no legacy preferences are intended, create/initialize the settings file so the loader succeeds, or bypass the migration path
Example fix
// before
Settings::load_legacy_route_preferences_read_only()?; // file missing
// after
if settings_path.exists() {
Settings::load_legacy_route_preferences_read_only()?;
} Defensive patterns
Strategy: fallback
Validate before calling
if !settings_path.exists() {
eprintln!("no legacy settings.toml; skipping preference migration");
} Try / catch
match migrate_result {
Err(e) if e.to_string().contains("Could not read legacy route preferences") => {
fix_settings_file_or_skip_migration();
}
other => other?,
} Prevention
- Check settings.toml existence/permissions before triggering migration flows
- Keep settings.toml writable by the running user
When it happens
Trigger: Calling mutate_config_document (triggering the migration) while the legacy settings file is missing, unreadable, or fails to load at the OS level (permissions, I/O error).
Common situations: Running the app in a fresh environment/home directory without a legacy settings.toml; restrictive file permissions on settings.toml; disk I/O issues.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Antigravity is a retired, non-runnable legacy provider…
- Antigravity is a retired, non-runnable legacy provider…
- Choose a model for the destination provider before…
- Config migration skipped
- Could not parse configuration for route preference…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/25dca53bbfaa76dc.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/config_persistence.rs:57
doc: &mut toml_edit::DocumentMut,
) -> anyhow::Result<()> {
if !crate::config::is_home_config_path(path)
|| doc
.get("route_preferences_version")
.and_then(toml_edit::Item::as_integer)
.is_some()
{
return Ok(());
}
let mut config: crate::config::Config = toml::from_str(&doc.to_string()).map_err(|_| {
anyhow::anyhow!(
"Could not parse configuration for route preference migration; contents omitted"
)
})?;
let previous_config = config.clone();
let settings =
crate::settings::Settings::load_legacy_route_preferences_read_only().map_err(|_| {
anyhow::anyhow!(
"Could not read legacy route preferences; configuration was not changed"
)
})?;
// An unparsable settings.toml loads as defaults carrying `load_error`, which
// keeps the UI usable but is not evidence that no preferences were saved.
// This migration is one-way: stamping the version over defaults would retire
// the user's real legacy choices unread. Refuse instead, exactly as
// `Settings::save_to_path` refuses to overwrite an unreadable document.
// Contents stay omitted; the file may hold private text.
anyhow::ensure!(
settings.load_error.is_none(),
"Could not read legacy route preferences; configuration was not changed"
);
config.apply_saved_selection(&settings);
let active_identity = config.active_provider_identity(config.api_provider()).ok();
let selector = active_identity
.as_ref()
.and_then(|identity| {View on GitHub (pinned to 73e0f67d83)