{"record":{"id":"b4a1b8026805b321","repo":"astrid-runtime/astrid","slug":"failed-to-persist-e","errorCode":null,"errorMessage":"failed to persist {}: {e}","messagePattern":"failed to persist (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-capsule-install/src/meta.rs","lineNumber":113,"sourceCode":"            );\n            None\n        },\n    }\n}\n\n/// Write `meta.json` to the capsule's install directory.\n///\n/// Uses atomic write (temp file + rename) to avoid corruption from\n/// crashes or power loss during write.\npub fn write_meta(target_dir: &Path, meta: &CapsuleMeta) -> anyhow::Result<()> {\n    let meta_path = target_dir.join(\"meta.json\");\n    let json = serde_json::to_string_pretty(meta).context(\"failed to serialize meta.json\")?;\n    let mut tmp = tempfile::NamedTempFile::new_in(target_dir)\n        .context(\"failed to create temp file for meta.json\")?;\n    std::io::Write::write_all(&mut tmp, json.as_bytes())\n        .context(\"failed to write meta.json staging\")?;\n    tmp.persist(&meta_path)\n        .map_err(|e| anyhow::anyhow!(\"failed to persist {}: {e}\", meta_path.display()))?;\n    Ok(())\n}\n\n/// Where an installed capsule lives.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum CapsuleLocation {\n    /// User-level: `~/.astrid/capsules/`\n    User,\n    /// Workspace-level: capsules under the selected project state directory.\n    Workspace,\n}\n\nimpl fmt::Display for CapsuleLocation {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::User => f.write_str(\"user\"),\n            Self::Workspace => f.write_str(\"workspace\"),\n        }","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-capsule-install/src/meta.rs#L95-L131","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n// running install as user without write access to ~/.astrid/capsules/foo\nsudo ./capsule install ./foo\n// after\nsudo chown -R \"$USER\" ~/.astrid/capsules/foo\n./capsule install ./foo","handlingStrategy":"try-catch","validationCode":"// before install\ndir.parent().ok_or(\"no parent\")?;\nlet probe = dir.join(\".write-test\");\nstd::fs::write(&probe, b\"\").map_err(|e| format!(\"target not writable: {e}\"))?;\nstd::fs::remove_file(&probe)?;","typeGuard":null,"tryCatchPattern":"match install_from_local_path(&path) {\n    Err(e) if e.to_string().contains(\"failed to persist\") => {\n        eprintln!(\"meta.json persist failed: {e:#}; check permissions/df\");\n    }\n    other => other?,\n}","preventionTips":["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."],"tags":["file-write","atomic-persist","meta"],"backgroundTag":"file-write-failed","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}