libnyanpasu/clash-nyanpasu · error

materialization journal hash is invalid

Error message

materialization journal hash is invalid

What it means

The journal's `hash` field must be exactly 64 ASCII hex characters (a SHA-256 hex digest) recording the content hash of the managed target. `read_journal` rejects journals whose hash has the wrong length or non-hex characters, because a malformed hash cannot be compared against recomputed content hashes during recovery/verification.

Source

Thrown at backend/tauri/src/service/profile_file.rs:633

            );
        }
        let content = std::fs::read_to_string(path)
            .with_context(|| format!("read materialization journal {}", path.display()))?;
        let journal: MaterializationJournal = serde_yaml::from_str(&content)
            .with_context(|| format!("parse materialization journal {}", path.display()))?;
        if journal.operation_id != operation_id || !valid_operation_id(&journal.operation_id) {
            bail!("materialization journal operation id mismatch");
        }
        if journal
            .managed_path
            .as_path()
            .components()
            .any(|component| is_materialization_root_name(component.as_os_str()))
        {
            bail!("materialization journal targets reserved private storage");
        }
        if journal.hash.len() != 64 || !journal.hash.bytes().all(|byte| byte.is_ascii_hexdigit()) {
            bail!("materialization journal hash is invalid");
        }
        Ok(journal)
    }

    fn remove_nofollow(path: &Path) -> anyhow::Result<()> {
        match std::fs::symlink_metadata(path) {
            Ok(metadata) if metadata.is_dir() && !is_symlink_or_reparse(&metadata) => {
                bail!(
                    "refusing to remove directory as a profile resource: {}",
                    path.display()
                )
            }
            Ok(_) => {
                std::fs::remove_file(path)
                    .with_context(|| format!("remove profile resource {}", path.display()))?;
                sync_directory(path.parent().expect("profile resource has parent"))
            }
            Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Delete the corrupt journal so the operation is re-derived and a fresh journal with a valid hash is written
  2. Re-materialize the profile; the hash is recomputed from actual content
  3. If inspecting, verify the hash is 64 hex chars matching a SHA-256 of the staged content
  4. Avoid editing journal YAML by hand

Example fix

// before (journal YAML)
// hash: abc123
hash: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
// after: full 64-char lowercase hex SHA-256 digest
Defensive patterns

Strategy: validation

Validate before calling

fn valid_sha256_hex(h: &str) -> bool {
    h.len() == 64 && h.bytes().all(|b| b.is_ascii_hexdigit())
}
// check before writing or trusting a journal hash

Type guard

fn has_valid_hash(j: &MaterializationJournal) -> bool {
    valid_sha256_hex(&j.hash)
}

Try / catch

match read_journal(&path, &op_id) {
    Err(e) if e.to_string().contains("hash is invalid") => {
        let _ = std::fs::remove_file(&path); // corrupt journal; regenerate via materialization
    }
    Err(e) => return Err(e),
    Ok(j) => use_journal(j),
}

Prevention

When it happens

Trigger: `read_journal` parses a journal where `hash` is empty, truncated, uppercase-with-symbols, base64, or otherwise not 64 chars of [0-9a-f]. Caused by hand-edited journals, corruption, or a journal written by an incompatible/older schema.

Common situations: Manually edited YAML; truncated file from a disk/sync issue; journal produced by a different tool version using a different hash encoding.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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