{"record":{"id":"82a91165d5146172","repo":"libnyanpasu/clash-nyanpasu","slug":"failed-to-serialize-migrated-profiles-e","errorCode":null,"errorMessage":"failed to serialize migrated profiles: {e}","messagePattern":"failed to serialize migrated profiles: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/core/migration/modules/profiles.rs","lineNumber":262,"sourceCode":"\n    // R15: backup first, then transform (D3: mandatory .bak)\n    let bak = path.with_extension(\"yaml.bak\");\n    crate::core::migration::fs::atomic_write(&bak, raw.as_bytes())?;\n\n    let migrated = migrate_clean_schema(doc)?;\n\n    // Typed round-trip: the only accepted output is a document the new domain\n    // model can load AND validate (design §14.4). Duplicate uids are rejected\n    // here by the items deserializer (R13).\n    let profiles: nyanpasu_config::profile::Profiles =\n        serde_yaml::from_value(Value::Mapping(migrated))\n            .map_err(|e| anyhow::anyhow!(\"clean-schema output rejected by domain model: {e}\"))?;\n    profiles\n        .validate()\n        .map_err(|errors| anyhow::anyhow!(\"clean-schema output failed validation: {errors:?}\"))?;\n\n    let body = serde_yaml::to_string(&profiles)\n        .map_err(|e| anyhow::anyhow!(\"failed to serialize migrated profiles: {e}\"))?;\n    let content = format!(\"# Profiles Config for Clash Nyanpasu\\n\\n{body}\");\n    crate::core::migration::fs::atomic_write(&path, content.as_bytes())?;\n    Ok(())\n}\n\nfn rollback_clean_schema(ctx: &mut Ctx) -> anyhow::Result<()> {\n    let path = ctx.profiles_path();\n    let bak = path.with_extension(\"yaml.bak\");\n    if !bak.exists() {\n        eprintln!(\"profiles.yaml.bak not found, nothing to roll back\");\n        return Ok(());\n    }\n    let raw = std::fs::read(&bak)?;\n    crate::core::migration::fs::atomic_write(&path, &raw)\n}\n\n#[derive(Debug, thiserror::Error)]\n#[error(\"profiles clean-schema migration failed (uid={uid:?}, field={field_path}): {reason}\")]","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/core/migration/modules/profiles.rs#L244-L280","documentation":"Once the migrated document passes domain validation, run_clean_schema serializes the typed Profiles back to YAML with serde_yaml::to_string. Serialization of the validated domain model should rarely fail, but if it does (non-string mapping keys, unsupported value types introduced by a model change), the migration aborts before the atomic write.","triggerScenarios":"serde_yaml::to_string(&profiles) fails — practically only when the domain model contains values serde_yaml cannot represent (e.g. non-string map keys, nested types changed by a model update) or a serde serialize impl on a Profiles field returns an error.","commonSituations":"Version skew between nyanpasu-config and the migration code where a new field type is not YAML-serializable; a custom Serialize impl returning Err; extremely unusual profile data surviving validation but breaking the serializer.","solutions":["Align the nyanpasu-config crate version with the migration code (rebuild so both use the same Profiles model).","Inspect {e} to identify the unserializable field/type and fix the model or transform.","This indicates a code bug, not user data: report it with the error message if it reproduces on a normal profiles file.","As a workaround, restore profiles.yaml.bak to keep the legacy file usable until the bug is fixed."],"exampleFix":"// before\nlet body = serde_yaml::to_string(&profiles)\n    .map_err(|e| anyhow::anyhow!(\"failed to serialize migrated profiles: {e}\"))?;\n// after\nlet body = serde_yaml::to_string(&profiles)\n    .with_context(|| \"failed to serialize migrated profiles — check nyanpasu-config Profiles model for YAML-incompatible types\")?;","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"let body = serde_yaml::to_string(&profiles).map_err(|e| {\n    eprintln!(\"serialize failed (code bug, data untouched): {e}\");\n    anyhow::anyhow!(\"failed to serialize migrated profiles: {e}\")\n})?; // restore profiles.yaml.bak; file was not written","preventionTips":["Pin nyanpasu-config and migration code to compatible versions","Add a round-trip test (to_string then from_str) over Profiles in CI","Avoid custom field types without YAML-compatible Serialize impls","Treat any occurrence as a bug report trigger — validated models should always serialize"],"tags":["yaml","migration","profiles","serialization"],"backgroundTag":"json-marshal-failed","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"}