astrid-runtime/astrid · error · io::Error
InvalidData
InvalidData
Error message
invalid private-file write journal
What it means
When recovering, read_private_file_transaction_journal parses the journal JSON and then validate_private_file_transaction checks its integrity: version must be 1, the transaction id a 32-hex-char UUID, target/staged/rollback names single path components containing the id, had_live consistent with rollback/old_hash presence, and both digests 64 hex chars. Any violation means the journal is corrupt or tampered with, so recovery refuses with InvalidData.
Source
Thrown at crates/astrid-core/src/platform_fs/windows/private_file.rs:300
.is_some_and(|name| !is_single_path_component(OsStr::new(name)))
|| !journal.staged.contains(&journal.transaction_id)
|| journal
.rollback
.as_deref()
.is_some_and(|name| !name.contains(&journal.transaction_id))
|| journal
.legacy_displaced
.as_deref()
.is_some_and(|name| !name.contains(&journal.transaction_id))
|| journal.had_live != journal.rollback.is_some()
|| journal.had_live != journal.old_hash.is_some()
|| !valid_digest(&journal.new_hash)
|| journal
.old_hash
.as_deref()
.is_some_and(|hash| !valid_digest(hash))
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"invalid private-file write journal",
));
}
Ok(())
}
pub(super) fn is_single_path_component(value: &OsStr) -> bool {
let mut components = Path::new(value).components();
matches!(components.next(), Some(Component::Normal(_))) && components.next().is_none()
}
pub(super) fn finish_private_file_transaction(
parent: &Path,
journal: &PrivateFileTransaction,
guard: &TrustedPathGuard,
) -> io::Result<()> {
guardView on GitHub (pinned to affd8760f4)
Solutions
- Inspect .astrid-private-write.transaction.json; if it is corrupt and no live data depends on it, remove the journal and its .astrid-private.* companion files so the next operation starts clean (this discards the pending transaction's rollback).
- Verify the live target file's contents manually before deleting the journal; if the write actually completed, the data is intact and only the journal is stale.
- Check library version consistency: journals written by other versions may fail validation; upgrade/downgrade to the version that wrote the journal to recover it properly.
Example fix
// before: recovery keeps failing with InvalidData on a corrupt journal
// after: manually clear the pending transaction after confirming the target file
if std::fs::read(&state).map(|d| sha256(&d) == expected).unwrap_or(false) {
std::fs::remove_file(dir.join(".astrid-private-write.transaction.json")).ok();
atomic_write_private_file(&state, data)?;
} Defensive patterns
Strategy: try-catch
Try / catch
match result {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains("invalid private-file write journal") => {
// journal corrupt: verify live file, remove journal + .astrid-private.* files, retry
}
other => other?,
} Prevention
- Never hand-edit journal files.
- Keep library versions consistent across writers.
- Enable disk error monitoring (chkdsk/S.M.A.R.T.).
When it happens
Trigger: The journal file on disk was truncated, hand-edited, corrupted by a crash/partial flush, or written by an incompatible library version; the file passes JSON parsing but fails structural validation.
Common situations: Disk corruption or incomplete flush after power loss; a user manually edited/deleted parts of the journal; downgrading the library so an older/newer journal shape fails the deny_unknown_fields parse or version check.
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
- AlreadyExists
- MCP gateway attach is only supported on Unix hosts
- MCP gateway is only supported on Unix hosts
- Unsupported Windows architecture: {arch}
- mountpoint must be absolute
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/d703cd9dea54221e.
Report an issue: GitHub.