libnyanpasu/clash-nyanpasu · error

failed to parse profiles: {e}

Error message

failed to parse profiles: {e}

What it means

Raised by the profiles migration module's `detect_baseline` when the profiles YAML file exists but cannot be deserialized into a serde_yaml Mapping. This function inspects the current schema to decide the starting revision for the migration; if the file is unparseable, baseline detection aborts with this error. The raw serde_yaml diagnostic is embedded in the message.

Source

Thrown at backend/tauri/src/core/migration/modules/profiles.rs:34

static CLEAN_SCHEMA: MigrateProfilesCleanSchema = MigrateProfilesCleanSchema;
static STEPS: [&dyn MigrationStep; 3] = [&NULL_VALUE, &SCRIPT_NEWTYPE, &CLEAN_SCHEMA];

pub struct ProfilesMigrator;

impl ModuleMigrator for ProfilesMigrator {
    fn module(&self) -> &'static str {
        "profiles"
    }

    fn detect_baseline(&self, ctx: &Ctx) -> anyhow::Result<u64> {
        let profiles_path = ctx.profiles_path();
        if !profiles_path.exists() {
            return Ok(current_revision());
        }

        let raw = std::fs::read_to_string(&profiles_path)?;
        let profiles: Mapping = serde_yaml::from_str(&raw)
            .map_err(|e| anyhow::anyhow!("failed to parse profiles: {e}"))?;
        if is_clean_schema(&profiles) {
            return Ok(current_revision());
        }
        Ok(0)
    }

    fn steps(&self) -> &'static [&'static dyn MigrationStep] {
        &STEPS
    }
}

#[derive(Debug, Clone, Copy)]
pub struct MigrateProfilesNullValue;

impl MigrationStep for MigrateProfilesNullValue {
    fn id(&self) -> &'static str {
        "profiles/null_value"
    }

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Fix the YAML syntax error in the profiles file at the line/column given in the embedded serde_yaml message.
  2. Back up profiles.yaml, then validate it with a standalone YAML linter/parser before restoring.
  3. If unrecoverable, move the file aside (rename to profiles.yaml.bak) so detection treats it as absent and the app regenerates a clean schema.
  4. Verify the root of the document is a mapping (key: value pairs), not a bare sequence or scalar.

Example fix

// before (profiles.yaml truncated by crash)
items:
  - uid: abc
    name: Profile
    type: remote
    url: "https://example  // unterminated quote
// after
items:
  - uid: abc
    name: Profile
    type: remote
    url: "https://example.com/prof.yaml"
Defensive patterns

Strategy: validation

Validate before calling

fn profiles_parsable(raw: &str) -> bool {
    serde_yaml::from_str::<serde_yaml::Mapping>(raw).is_ok()
}
// before detect_baseline: let ok = std::fs::read_to_string(&path).map(|r| profiles_parsable(&r)).unwrap_or(false);

Type guard

fn root_is_mapping(raw: &str) -> bool {
    serde_yaml::from_str::<serde_yaml::Value>(raw)
        .map(|v| v.is_mapping())
        .unwrap_or(false)
}

Try / catch

let profiles: Mapping = match serde_yaml::from_str(&raw) {
    Ok(m) => m,
    Err(e) => {
        eprintln!("profiles.yaml unparseable, treating baseline as absent: {e}");
        return Ok(0); // fall back to revision 0
    }
};

Prevention

When it happens

Trigger: Running migration baseline detection when `profiles_path()` exists but its content is invalid YAML or its root node is not a mapping (e.g. a list or scalar document).

Common situations: Manually edited profiles.yaml with a syntax slip; file truncated by disk-full or crash; a subscription importer wrote malformed YAML; empty file left behind by a failed earlier run.

Understand the failure class

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/14e9f434b9ae67a8. Report an issue: GitHub.