{"record":{"id":"fb7b5778ea3dc128","repo":"astrid-runtime/astrid","slug":"local-capsule-source-source-is-not-a-regular-f","errorCode":null,"errorMessage":"local capsule source {source:?} is not a regular file","messagePattern":"local capsule source (.+?) is not a regular file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/distro/local_source.rs","lineNumber":83,"sourceCode":"        .components()\n        .any(|component| matches!(component, Component::ParentDir))\n    {\n        bail!(\"local capsule source {source:?} escapes the authenticated Distro.toml directory\");\n    }\n\n    let canonical_root = root\n        .canonicalize()\n        .with_context(|| format!(\"failed to resolve Distro.toml directory {}\", root.display()))?;\n    let canonical_path = candidate\n        .canonicalize()\n        .with_context(|| format!(\"failed to resolve local capsule source {source:?}\"))?;\n    if !canonical_path.starts_with(&canonical_root) {\n        bail!(\"local capsule source {source:?} escapes the authenticated Distro.toml directory\");\n    }\n    let metadata = std::fs::metadata(&canonical_path)\n        .with_context(|| format!(\"failed to stat local capsule source {source:?}\"))?;\n    if !metadata.is_file() {\n        bail!(\"local capsule source {source:?} is not a regular file\");\n    }\n    if metadata.len() > MAX_MEMBER_BYTES {\n        bail!(\n            \"local capsule source {source:?} is {} bytes, exceeding the \\\n             {MAX_MEMBER_BYTES}-byte member limit\",\n            metadata.len()\n        );\n    }\n\n    Ok(Some(canonical_path))\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn resolves_relative_member_from_manifest_parent() {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/distro/local_source.rs#L65-L101","documentation":"Once the capsule path is verified to be inside the authenticated root, its filesystem metadata is checked; if the target is not a regular file (directory, socket, fifo, device), resolve_local_capsule_archive rejects it. Capsule members must be regular archive files.","triggerScenarios":"The source path in Distro.toml points to a directory or special file instead of a .capsule archive; a dangling/odd symlink resolves to a non-file.","commonSituations":"Typo in the source path resolving to a directory; creating a capsule directory where the file was expected; build output not yet produced leaving a placeholder.","solutions":["Point the source at the actual capsule archive file, not a directory","Build the capsule first so the regular file exists at the referenced path","Verify with `ls -l` that the referenced path is a regular file"],"exampleFix":"// before\nsource = \"capsules/core\"          # a directory\n// after\nsource = \"capsules/core.capsule\"  # the archive file","handlingStrategy":"validation","validationCode":"let md = std::fs::metadata(capsule_path)?;\nif !md.is_file() {\n    anyhow::bail!(\"capsule source must be a regular file\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build capsules before sealing so the referenced files exist","Reference the .capsule archive file, never its containing directory","Verify referenced paths with `ls -l` after changing project layout"],"tags":["manifest","filesystem","capsule"],"backgroundTag":"file-not-found","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"}