{"record":{"id":"79d518406374960b","repo":"libnyanpasu/clash-nyanpasu","slug":"failed-to-serialize-profiles-e","errorCode":null,"errorMessage":"failed to serialize profiles: {e}","messagePattern":"failed to serialize profiles: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/core/migration/modules/profiles.rs","lineNumber":827,"sourceCode":"    if let Some(valid) = doc.get(\"valid\")\n        && !valid.is_null()\n    {\n        out.insert(\"valid\".into(), valid.clone());\n    }\n    out.insert(\"items\".into(), Value::Sequence(new_items));\n    Ok(out)\n}\n\n/// Atomically persist a profiles mapping, mirroring [`crate::utils::help::save_yaml`]\n/// but writing through a temp file + rename so a crash mid-write can never\n/// truncate the user's `profiles.yaml`.\nfn write_profiles_atomic(\n    path: &std::path::Path,\n    profiles: &Mapping,\n    prefix: Option<&str>,\n) -> anyhow::Result<()> {\n    let body = serde_yaml::to_string(profiles)\n        .map_err(|e| anyhow::anyhow!(\"failed to serialize profiles: {e}\"))?;\n    let content = match prefix {\n        Some(prefix) => format!(\"{prefix}\\n\\n{body}\"),\n        None => body,\n    };\n    crate::core::migration::fs::atomic_write(path, content.as_bytes())\n}\n\nfn current_revision() -> u64 {\n    STEPS.last().map(|step| step.revision()).unwrap_or_default()\n}\n\nfn migrate_profile_data(mut mapping: Mapping) -> Mapping {\n    if let Some(items) = mapping.get_mut(\"items\")\n        && let Some(items) = items.as_sequence_mut()\n    {\n        for item in items {\n            if let Some(item) = item.as_mapping_mut()\n                && let Some(ty) = item.get(\"type\").cloned()","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/core/migration/modules/profiles.rs#L809-L845","documentation":"write_profiles_atomic serializes the profiles Mapping to YAML and atomically writes it to disk; it is used by both the migration run and rollback paths. If serde_yaml::to_string fails on the Mapping, the write is aborted with this error and the on-disk profiles file is left untouched (atomic write never starts).","triggerScenarios":"serde_yaml::to_string(profiles) errors because the Mapping contains values serde_yaml cannot serialize — non-string keys outside serde_yaml's supported set, or values produced upstream that violate serde_yaml's model.","commonSituations":"A migration transform inserted an exotic value (e.g. tagged or non-string-keyed data) into the Mapping; version-skew between serde_yaml and produced types; practically rare since inputs originate from parsed YAML.","solutions":["Trace which transform produced the Mapping and ensure it only inserts serde_yaml-supported values (string keys, scalars, sequences, mappings).","Inspect {e} for the offending key/type and fix the transform to coerce it (e.g. stringify keys).","Restore profiles.yaml.bak — the error means the original file was not modified.","If it comes from parsed user data, round-trip the Mapping (to_string then from_str) early to catch unserializable content before mutation."],"exampleFix":"// before\nlet body = serde_yaml::to_string(profiles)\n    .map_err(|e| anyhow::anyhow!(\"failed to serialize profiles: {e}\"))?;\n// after\nlet body = serde_yaml::to_string(profiles)\n    .with_context(|| format!(\"failed to serialize profiles for {} — Mapping contains unserializable values\", path.display()))?;","handlingStrategy":"try-catch","validationCode":"fn mapping_round_trips(m: &serde_yaml::Mapping) -> bool {\n    serde_yaml::to_string(m)\n        .ok()\n        .and_then(|s| serde_yaml::from_str::<serde_yaml::Mapping>(&s).ok())\n        .is_some()\n}","typeGuard":"null","tryCatchPattern":"let body = match serde_yaml::to_string(profiles) {\n    Ok(b) => b,\n    Err(e) => {\n        eprintln!(\"profiles Mapping unserializable, original file untouched: {e}\");\n        return Err(anyhow::anyhow!(\"failed to serialize profiles: {e}\"));\n    }\n};","preventionTips":["Only insert serde_yaml-native values (string keys, scalars, sequences, mappings) in transforms","Round-trip test the Mapping after each transform step in tests","Keep serde_yaml versions consistent across crates","Fail fast right after mutation by serializing before the atomic write (as this code does)"],"tags":["yaml","migration","profiles","serialization","atomic-write"],"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"}