libnyanpasu/clash-nyanpasu · error
failed to serialize profiles: {e}
Error message
failed to serialize profiles: {e} What it means
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).
Source
Thrown at backend/tauri/src/core/migration/modules/profiles.rs:827
if let Some(valid) = doc.get("valid")
&& !valid.is_null()
{
out.insert("valid".into(), valid.clone());
}
out.insert("items".into(), Value::Sequence(new_items));
Ok(out)
}
/// Atomically persist a profiles mapping, mirroring [`crate::utils::help::save_yaml`]
/// but writing through a temp file + rename so a crash mid-write can never
/// truncate the user's `profiles.yaml`.
fn write_profiles_atomic(
path: &std::path::Path,
profiles: &Mapping,
prefix: Option<&str>,
) -> anyhow::Result<()> {
let body = serde_yaml::to_string(profiles)
.map_err(|e| anyhow::anyhow!("failed to serialize profiles: {e}"))?;
let content = match prefix {
Some(prefix) => format!("{prefix}\n\n{body}"),
None => body,
};
crate::core::migration::fs::atomic_write(path, content.as_bytes())
}
fn current_revision() -> u64 {
STEPS.last().map(|step| step.revision()).unwrap_or_default()
}
fn migrate_profile_data(mut mapping: Mapping) -> Mapping {
if let Some(items) = mapping.get_mut("items")
&& let Some(items) = items.as_sequence_mut()
{
for item in items {
if let Some(item) = item.as_mapping_mut()
&& let Some(ty) = item.get("type").cloned()View on GitHub (pinned to f7dbce2997)
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.
Example fix
// before
let body = serde_yaml::to_string(profiles)
.map_err(|e| anyhow::anyhow!("failed to serialize profiles: {e}"))?;
// after
let body = serde_yaml::to_string(profiles)
.with_context(|| format!("failed to serialize profiles for {} — Mapping contains unserializable values", path.display()))?; Defensive patterns
Strategy: try-catch
Validate before calling
fn mapping_round_trips(m: &serde_yaml::Mapping) -> bool {
serde_yaml::to_string(m)
.ok()
.and_then(|s| serde_yaml::from_str::<serde_yaml::Mapping>(&s).ok())
.is_some()
} Type guard
null
Try / catch
let body = match serde_yaml::to_string(profiles) {
Ok(b) => b,
Err(e) => {
eprintln!("profiles Mapping unserializable, original file untouched: {e}");
return Err(anyhow::anyhow!("failed to serialize profiles: {e}"));
}
}; Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to serialize migrated profiles: {e}
- failed to parse profiles: {e}
- failed to serialize config: {e}
- unrecognized typed config migration state: existing {} is ne
- clean-schema output rejected by domain model: {e}
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/79d518406374960b.
Report an issue: GitHub.