{"record":{"id":"3d5b5f7c5829632f","repo":"astrid-runtime/astrid","slug":"workspace-capsule-component-must-be-relative","errorCode":null,"errorMessage":"workspace capsule component must be relative: {}","messagePattern":"workspace capsule component must be relative: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":1463,"sourceCode":"                .map_err(|error| {\n                    anyhow::anyhow!(\"workspace capsule tree contains an unsafe redirect: {error}\")\n                })?;\n        }\n        Ok(())\n    }\n\n    #[cfg(not(all(target_arch = \"wasm32\", target_os = \"unknown\")))]\n    fn verify_workspace_component_paths(\n        &self,\n        dir: &Path,\n        manifest: &astrid_capsule_types::manifest::CapsuleManifest,\n    ) -> anyhow::Result<()> {\n        let Ok(capsule_relative) = dir.strip_prefix(self.workspace_selection.state_dir()) else {\n            return Ok(());\n        };\n        for component in &manifest.components {\n            if component.path.is_absolute() {\n                anyhow::bail!(\n                    \"workspace capsule component must be relative: {}\",\n                    component.path.display()\n                );\n            }\n            self.workspace_selection\n                .resolve_file(capsule_relative.join(&component.path))\n                .map_err(|error| {\n                    anyhow::anyhow!(\n                        \"workspace capsule component path is unsafe ({}): {error}\",\n                        component.path.display()\n                    )\n                })?;\n        }\n        Ok(())\n    }\n\n    /// Verify an installed capsule against the authority source selected by\n    /// this runtime. Native daemon loads use the packed System catalog; the","sourceCodeStart":1445,"sourceCodeEnd":1481,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L1445-L1481","documentation":"This error means a component path in the workspace capsule's manifest was absolute, but workspace capsules are required to reference their components relative to the capsule's directory inside the workspace state dir. The library throws it while resolving workspace capsule components to guarantee all component files stay contained within the workspace capsule's own subtree (path-escape protection). Absolute paths are rejected rather than resolved to prevent capsules from pointing at arbitrary filesystem locations.","triggerScenarios":"Resolving a workspace capsule (the code path that strips self.workspace_selection.state_dir() as the capsule dir prefix) when any entry in manifest.components has an is_absolute() path — e.g. a component declared as path = \"/abs/path/to/file\" or path = \"C:\\\\...\" in Capsule.toml.","commonSituations":"Hand-editing Capsule.toml and pasting an absolute path; a generator or script emitting absolute paths derived from the authoring machine; moving a capsule between machines where paths were recorded absolutely; copying an example config that used a machine-specific absolute path.","solutions":["Edit Capsule.toml so every [[components]] path is relative to the capsule directory (e.g. \"wasm/module.wasm\" instead of \"/home/user/.../module.wasm\")","If the path was generated, fix the generator/script to emit paths relative to the capsule root","Verify with a quick check: no component path should start with \"/\" (or a Windows drive letter) and no path should contain \"..\" escaping the capsule dir","Regenerate or repackage the capsule so the manifest is rewritten with relative paths"],"exampleFix":"# before (Capsule.toml)\n[[components]]\npath = \"/home/alice/build/capsule.wasm\"\n\n# after\n[[components]]\npath = \"build/capsule.wasm\"","handlingStrategy":"validation","validationCode":"for c in &manifest.components {\n    if c.path.is_absolute() {\n        return Err(format!(\"component path must be relative: {}\", c.path.display()));\n    }\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"must be relative\") => {\n        // fix Capsule.toml component paths; no retry will help\n    }\n    other => other?,\n}","preventionTips":["Always author component paths relative to the capsule directory","Add CI linting that rejects absolute component paths in Capsule.toml","Never paste machine-specific absolute paths into manifests","Test capsule packaging on a clean checkout to catch absolute-path leakage"],"tags":["config","path","validation","workspace","capsule-manifest"],"backgroundTag":"path-traversal-blocked","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"}