{"record":{"id":"de485c57dccc33c9","repo":"astrid-runtime/astrid","slug":"inspect-capsule-projection-error","errorCode":null,"errorMessage":"inspect capsule projection {}: {error}","messagePattern":"inspect capsule projection (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":1636,"sourceCode":"        fn walk(\n            root: &Path,\n            directory: &Path,\n            inventory: &mut ProjectionInventory,\n        ) -> anyhow::Result<()> {\n            for entry in std::fs::read_dir(directory).map_err(|error| {\n                anyhow::anyhow!(\"read capsule projection {}: {error}\", directory.display())\n            })? {\n                let entry = entry\n                    .map_err(|error| anyhow::anyhow!(\"read capsule projection entry: {error}\"))?;\n                let path = entry.path();\n                let relative = path.strip_prefix(root).map_err(|_| {\n                    anyhow::anyhow!(\"capsule projection escaped its root: {}\", path.display())\n                })?;\n                let relative_text = relative.to_str().ok_or_else(|| {\n                    anyhow::anyhow!(\"capsule projection path is not UTF-8: {}\", path.display())\n                })?;\n                let metadata = std::fs::symlink_metadata(&path).map_err(|error| {\n                    anyhow::anyhow!(\"inspect capsule projection {}: {error}\", path.display())\n                })?;\n                let file_type = metadata.file_type();\n                if file_type.is_symlink() {\n                    anyhow::bail!(\n                        \"capsule projection contains a symbolic link: {}\",\n                        path.display()\n                    );\n                }\n                if file_type.is_dir() {\n                    inventory.directories.insert(relative_text.to_owned());\n                    walk(root, &path, inventory)?;\n                } else if file_type.is_file() {\n                    inventory.files.insert(relative_text.to_owned());\n                } else {\n                    anyhow::bail!(\n                        \"capsule projection contains a special file: {}\",\n                        path.display()\n                    );","sourceCodeStart":1618,"sourceCodeEnd":1654,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L1618-L1654","documentation":"Thrown when `std::fs::symlink_metadata` fails for an entry in the capsule projection during the inventory walk. The metadata is needed to classify the entry (file/dir/symlink); if it cannot be inspected the walk cannot continue safely. The OS error is wrapped with the path.","triggerScenarios":"The entry vanished between `read_dir` and `symlink_metadata` (TOCTOU race), or lstat fails due to permissions or IO errors on the filesystem.","commonSituations":"Concurrent deletion during inventory; files on a failing or network mount; permission bits changed mid-walk.","solutions":["Retry the inventory walk after the concurrent mutation settles.","Ensure no other process deletes/modifies projection entries during the walk.","Check filesystem health and permissions for the reported path.","Capture the wrapped io::Error source for the exact OS errno."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match build_inventory(root) {\n    Err(e) if e.to_string().contains(\"inspect capsule projection\") => build_inventory(root),\n    other => other,\n}","preventionTips":["Prevent concurrent deletion of projection entries during walks.","Use local filesystems for projections when possible.","Capture the io::Error source to distinguish races from real IO faults."],"tags":["filesystem","io","rust","concurrency"],"backgroundTag":"file-read-failed","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}