astrid-runtime/astrid · error
failed to persist {}: {e}
Error message
failed to persist {}: {e} What it means
write_meta serializes meta.json to a temp file in the target directory and then atomically persists it over the final meta.json path. If tempfile's persist (rename) fails — cross-filesystem target, permission problem, or the destination being locked/removed — this error wraps the OS message with the full path.
Source
Thrown at crates/astrid-capsule-install/src/meta.rs:113
);
None
},
}
}
/// Write `meta.json` to the capsule's install directory.
///
/// Uses atomic write (temp file + rename) to avoid corruption from
/// crashes or power loss during write.
pub fn write_meta(target_dir: &Path, meta: &CapsuleMeta) -> anyhow::Result<()> {
let meta_path = target_dir.join("meta.json");
let json = serde_json::to_string_pretty(meta).context("failed to serialize meta.json")?;
let mut tmp = tempfile::NamedTempFile::new_in(target_dir)
.context("failed to create temp file for meta.json")?;
std::io::Write::write_all(&mut tmp, json.as_bytes())
.context("failed to write meta.json staging")?;
tmp.persist(&meta_path)
.map_err(|e| anyhow::anyhow!("failed to persist {}: {e}", meta_path.display()))?;
Ok(())
}
/// Where an installed capsule lives.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CapsuleLocation {
/// User-level: `~/.astrid/capsules/`
User,
/// Workspace-level: capsules under the selected project state directory.
Workspace,
}
impl fmt::Display for CapsuleLocation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::User => f.write_str("user"),
Self::Workspace => f.write_str("workspace"),
}View on GitHub (pinned to affd8760f4)
Solutions
- Check the wrapped OS error: fix permissions (chmod/chown) on the capsule target directory so the process can write meta.json.
- Verify the target directory and temp staging live on the same filesystem (persist is a rename).
- Free disk space if the filesystem is full.
- Retry the install; if the destination is locked by another process, close it or run when no other capsule operation is active.
Example fix
// before // running install as user without write access to ~/.astrid/capsules/foo sudo ./capsule install ./foo // after sudo chown -R "$USER" ~/.astrid/capsules/foo ./capsule install ./foo
Defensive patterns
Strategy: try-catch
Validate before calling
// before install
dir.parent().ok_or("no parent")?;
let probe = dir.join(".write-test");
std::fs::write(&probe, b"").map_err(|e| format!("target not writable: {e}"))?;
std::fs::remove_file(&probe)?; Try / catch
match install_from_local_path(&path) {
Err(e) if e.to_string().contains("failed to persist") => {
eprintln!("meta.json persist failed: {e:#}; check permissions/df");
}
other => other?,
} Prevention
- Ensure the capsule target directory is writable by the invoking user.
- Keep target and temp staging on the same filesystem; don't point installs at mount roots.
- Monitor disk space on the volume holding installed capsules.
- Avoid running multiple installers into the same target simultaneously.
When it happens
Trigger: Calling write_meta (directly or via install_from_local_path_internal or the remove-capsule dependency-validation path) when the staging temp file cannot be renamed onto meta_path: target dir on a different mount, read-only filesystem, or insufficient write permission on the destination.
Common situations: Installing into a capsule directory owned by another user or a read-only mount; disk full; antivirus/indexers holding the destination file on some platforms; target directory deleted between staging and persist.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- failed to persist {}: {e}
- failed to replace signed capsule archive: {error}
- failed to persist {}: {e}
- audit fixture
- non-empty audit
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/b4a1b8026805b321.
Report an issue: GitHub.