{"record":{"id":"b63b16dcd65e3df0","repo":"libnyanpasu/clash-nyanpasu","slug":"failed-to-parse-config-e","errorCode":null,"errorMessage":"failed to parse config: {e}","messagePattern":"failed to parse config: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/core/migration/modules/app_config.rs","lineNumber":40,"sourceCode":"\nconst NETWORK_STATISTIC_WIDGET_KEY: &str = \"network_statistic_widget\";\n\npub struct AppConfigMigrator;\n\nimpl ModuleMigrator for AppConfigMigrator {\n    fn module(&self) -> &'static str {\n        \"app_config\"\n    }\n\n    fn detect_baseline(&self, ctx: &Ctx) -> anyhow::Result<u64> {\n        let config_path = ctx.nyanpasu_config_path();\n        if !config_path.exists() {\n            return Ok(current_revision());\n        }\n\n        let raw = std::fs::read_to_string(&config_path)?;\n        let config: Mapping = serde_yaml::from_str(&raw)\n            .map_err(|e| anyhow::anyhow!(\"failed to parse config: {e}\"))?;\n        if needs_language_option_migration(&config)\n            || needs_theme_setting_migration(&config)\n            || needs_network_statistic_widget_migration(&config)\n            || needs_language_case_migration(&config)\n        {\n            Ok(0)\n        } else {\n            Ok(current_revision())\n        }\n    }\n\n    fn steps(&self) -> &'static [&'static dyn MigrationStep] {\n        &STEPS\n    }\n}\n\n#[derive(Debug, Clone, Copy)]\npub struct MigrateLanguageOption;","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/core/migration/modules/app_config.rs#L22-L58","documentation":"Thrown by the app_config migration module's `detect_baseline`, which reads the Nyanpasu config YAML and parses it into a `serde_yaml::Mapping` to decide whether migrations are needed. If the file's content is not valid YAML, `serde_yaml::from_str` fails and the error is wrapped as \"failed to parse config: {e}\" with serde_yaml's message appended. The file exists, but its content is unreadable as YAML.","triggerScenarios":"`detect_baseline` reads `ctx`'s nyanpasu config path, the file exists, but `serde_yaml::from_str::<Mapping>` fails — e.g. corrupt file, empty/garbage content, duplicate keys rejected by the parser, or the file was hand-edited with YAML syntax errors (bad indentation, tabs, unbalanced quotes).","commonSituations":"Crash or power loss mid-write leaving a truncated config; manual editing of the YAML config; a tool wrote JSON or another format into the YAML file; encoding issues from non-UTF-8 bytes on disk.","solutions":["Open the config file at the logged path and fix the YAML syntax error reported after the colon in the message","Restore the config from backup or delete/rename the corrupt file so the app regenerates defaults (note: settings will reset)","Validate the YAML with a linter (e.g. `yamltidy`/online parser) before saving hand edits","Ensure writes go through crash-safe paths like `atomic_write` instead of direct truncating writes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"fn config_yaml_is_valid(path: &std::path::Path) -> bool {\n    std::fs::read_to_string(path)\n        .ok()\n        .map(|raw| serde_yaml::from_str::<serde_yaml::Mapping>(&raw).is_ok())\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match detect_baseline(&ctx) {\n    Ok(rev) => rev,\n    Err(e) if e.to_string().contains(\"failed to parse config\") => {\n        log::warn!(\"config unreadable, treating as unmigrated default: {e:#}\");\n        backup_and_reset_config(&ctx);\n        current_revision()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Only write the config through `atomic_write` so crashes cannot truncate it","Validate YAML with a linter before saving hand edits","Keep timestamped backups of the config before upgrades/migrations","Ensure files are saved as UTF-8 and never overwritten with JSON or other formats"],"tags":["rust","yaml","serde","config"],"backgroundTag":"yaml-parse-error","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}