{"record":{"id":"25dca53bbfaa76dc","repo":"Hmbown/CodeWhale","slug":"could-not-read-legacy-route-preferences-configuration-was","errorCode":null,"errorMessage":"Could not read legacy route preferences; configuration was not changed","messagePattern":"Could not read legacy route preferences; configuration was not changed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/config_persistence.rs","lineNumber":57,"sourceCode":"    doc: &mut toml_edit::DocumentMut,\n) -> anyhow::Result<()> {\n    if !crate::config::is_home_config_path(path)\n        || doc\n            .get(\"route_preferences_version\")\n            .and_then(toml_edit::Item::as_integer)\n            .is_some()\n    {\n        return Ok(());\n    }\n    let mut config: crate::config::Config = toml::from_str(&doc.to_string()).map_err(|_| {\n        anyhow::anyhow!(\n            \"Could not parse configuration for route preference migration; contents omitted\"\n        )\n    })?;\n    let previous_config = config.clone();\n    let settings =\n        crate::settings::Settings::load_legacy_route_preferences_read_only().map_err(|_| {\n            anyhow::anyhow!(\n                \"Could not read legacy route preferences; configuration was not changed\"\n            )\n        })?;\n    // An unparsable settings.toml loads as defaults carrying `load_error`, which\n    // keeps the UI usable but is not evidence that no preferences were saved.\n    // This migration is one-way: stamping the version over defaults would retire\n    // the user's real legacy choices unread. Refuse instead, exactly as\n    // `Settings::save_to_path` refuses to overwrite an unreadable document.\n    // Contents stay omitted; the file may hold private text.\n    anyhow::ensure!(\n        settings.load_error.is_none(),\n        \"Could not read legacy route preferences; configuration was not changed\"\n    );\n    config.apply_saved_selection(&settings);\n    let active_identity = config.active_provider_identity(config.api_provider()).ok();\n    let selector = active_identity\n        .as_ref()\n        .and_then(|identity| {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/config_persistence.rs#L39-L75","documentation":"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.","triggerScenarios":"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).","commonSituations":"Running the app in a fresh environment/home directory without a legacy settings.toml; restrictive file permissions on settings.toml; disk I/O issues.","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"],"exampleFix":"// before\nSettings::load_legacy_route_preferences_read_only()?; // file missing\n// after\nif settings_path.exists() {\n    Settings::load_legacy_route_preferences_read_only()?;\n}","handlingStrategy":"fallback","validationCode":"if !settings_path.exists() {\n    eprintln!(\"no legacy settings.toml; skipping preference migration\");\n}","typeGuard":null,"tryCatchPattern":"match migrate_result {\n    Err(e) if e.to_string().contains(\"Could not read legacy route preferences\") => {\n        fix_settings_file_or_skip_migration();\n    }\n    other => other?,\n}","preventionTips":["Check settings.toml existence/permissions before triggering migration flows","Keep settings.toml writable by the running user"],"tags":["config","migration","file-read","settings"],"backgroundTag":"file-read-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}