libnyanpasu/clash-nyanpasu · error
clean-schema output failed validation: {errors:?}
Error message
clean-schema output failed validation: {errors:?} What it means
After successful deserialization into the domain model, run_clean_schema calls Profiles::validate() to enforce cross-field invariants (design §14.4). If validate() returns errors, the migration aborts with 'clean-schema output failed validation: {errors:?}' and the original file is left untouched (the .bak may already have been written).
Source
Thrown at backend/tauri/src/core/migration/modules/profiles.rs:259
if is_clean_schema(&doc) {
return Ok(());
}
// R15: backup first, then transform (D3: mandatory .bak)
let bak = path.with_extension("yaml.bak");
crate::core::migration::fs::atomic_write(&bak, raw.as_bytes())?;
let migrated = migrate_clean_schema(doc)?;
// Typed round-trip: the only accepted output is a document the new domain
// model can load AND validate (design §14.4). Duplicate uids are rejected
// here by the items deserializer (R13).
let profiles: nyanpasu_config::profile::Profiles =
serde_yaml::from_value(Value::Mapping(migrated))
.map_err(|e| anyhow::anyhow!("clean-schema output rejected by domain model: {e}"))?;
profiles
.validate()
.map_err(|errors| anyhow::anyhow!("clean-schema output failed validation: {errors:?}"))?;
let body = serde_yaml::to_string(&profiles)
.map_err(|e| anyhow::anyhow!("failed to serialize migrated profiles: {e}"))?;
let content = format!("# Profiles Config for Clash Nyanpasu\n\n{body}");
crate::core::migration::fs::atomic_write(&path, content.as_bytes())?;
Ok(())
}
fn rollback_clean_schema(ctx: &mut Ctx) -> anyhow::Result<()> {
let path = ctx.profiles_path();
let bak = path.with_extension("yaml.bak");
if !bak.exists() {
eprintln!("profiles.yaml.bak not found, nothing to roll back");
return Ok(());
}
let raw = std::fs::read(&bak)?;
crate::core::migration::fs::atomic_write(&path, &raw)
}View on GitHub (pinned to f7dbce2997)
Solutions
- Read the {errors:?} list to identify which invariants failed, and correct the corresponding entries in the source profiles.yaml before re-running migration.
- Restore from profiles.yaml.bak and retry migration on pristine data to rule out a previously corrupted half-migration.
- If validation fails on reasonable legacy data, treat it as a bug in the migration transform or in validate() and report with the errors list.
- Add a pre-check running the same validate() on a dry-run migrated copy to surface issues before committing.
Example fix
// before
profiles.validate()
.map_err(|errors| anyhow::anyhow!("clean-schema output failed validation: {errors:?}"))?;
// after
profiles.validate()
.with_context(|| format!("clean-schema validation failed for {} — restore .yaml.bak and fix source data", path.display()))?; Defensive patterns
Strategy: validation
Validate before calling
if let Err(errors) = profiles.validate() {
return Err(anyhow::anyhow!("pre-commit validation failed: {errors:?}"));
} // run this on the in-memory Profiles before any serialization/write Type guard
fn is_valid_profiles(p: &nyanpasu_config::profile::Profiles) -> bool {
p.validate().is_ok()
} Try / catch
if let Err(errors) = profiles.validate() {
eprintln!("clean-schema output failed validation: {errors:?}");
eprintln!("profiles.yaml left untouched; restore .yaml.bak if needed");
return Err(anyhow::anyhow!("validation failed: {errors:?}"));
} Prevention
- Dry-run the transform + validate() on a copy of the data before committing
- Cover known legacy-data quirks with validate() unit tests
- Surface the structured {errors:?} list to users instead of a generic failure
- Keep domain invariants and the migration transform updated together
When it happens
Trigger: The migrated document deserializes fine but violates domain invariants checked by Profiles::validate() — e.g. structurally valid items with semantically invalid combinations, dangling references, or constraint violations not expressible in serde.
Common situations: Legacy data that serde accepts but the new model's semantic rules reject (e.g. duplicate references after transform, ordering/current-pointer inconsistencies); a migration-transform bug producing semantically inconsistent output.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- clean-schema output rejected by domain model: {e}
- profiles.yaml failed validation: {errors:?}
- failed to parse profiles: {e}
- failed to serialize migrated profiles: {e}
- failed to serialize profiles: {e}
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/fec97d5d5d9a41e0.
Report an issue: GitHub.