astrid-runtime/astrid · error
legacy capsule component path is not relative
Error message
legacy capsule component path is not relative
What it means
canonical_legacy_archive (legacy native-capsule migration) validates each legacy component's path from its metadata and rejects paths that are not relative — i.e. containing RootDir or ParentDir components. This prevents a legacy manifest with an absolute or escaping path from writing outside the staging directory during migration.
Source
Thrown at crates/astrid-capsule-install/src/storage.rs:652
fn canonical_legacy_archive(
home: &astrid_core::dirs::AstridHome,
target: &Path,
meta: &CapsuleMeta,
manifest: &astrid_capsule::manifest::CapsuleManifest,
) -> anyhow::Result<Vec<u8>> {
let staging = tempfile::tempdir().context("stage legacy capsule for migration")?;
copy_legacy_tree(target, staging.path())?;
if let Some(component) = manifest.components.first() {
let component_path = component.path.clone();
if component_path.is_absolute()
|| component_path.components().any(|part| {
matches!(
part,
std::path::Component::ParentDir | std::path::Component::RootDir
)
})
{
bail!("legacy capsule component path is not relative");
}
let Some(hash) = meta.wasm_hash.as_deref() else {
bail!("legacy capsule metadata has no WASM hash");
};
let wasm = home.bin_dir().join(format!("{hash}.wasm"));
let destination = staging.path().join(component_path);
if let Some(parent) = destination.parent() {
fs::create_dir_all(parent)?;
}
fs::copy(&wasm, &destination).with_context(|| {
format!("restore content-addressed WASM blob for {}", wasm.display())
})?;
}
for (relative, hash) in &meta.wit_files {
let relative = Path::new(relative);
if relative.is_absolute()
|| relative.components().any(|part| {
matches!(View on GitHub (pinned to affd8760f4)
Solutions
- Fix the legacy capsule meta so component_path is a plain relative path (e.g. "components/foo.wasm").
- Re-register/re-install the legacy capsule with current tooling so metadata is regenerated correctly.
- Remove the broken legacy capsule and let migration skip/re-create it from the source component.
Example fix
// before (legacy meta.toml) component_path = "/home/user/.astrid/capsules/foo.wasm" // after component_path = "components/foo.wasm"
Defensive patterns
Strategy: validation
Validate before calling
let p = std::path::PathBuf::from(&meta.component_path);
if p.is_absolute()
|| p.components().any(|c| matches!(c, std::path::Component::ParentDir | std::path::Component::RootDir))
{
anyhow::bail!("legacy component_path must be relative: {}", meta.component_path);
} Try / catch
match migrate_native_capsules_with_report(&home) {
Err(e) if e.to_string().contains("not relative") => {
warn!("legacy capsule has bad component path; fixing meta and retrying");
fix_legacy_component_paths(&home)?;
migrate_native_capsules_with_report(&home)?;
}
other => other,
} Prevention
- Keep legacy meta component_path relative; never store absolute install paths.
- Validate legacy meta files once up front before starting migration.
- Regenerate legacy metadata with current tooling instead of hand-editing.
When it happens
Trigger: Running migrate_native_capsules_with_report where a legacy capsule's meta stores component_path such as "/abs/component.wasm", "../component.wasm", or "a/../../b".
Common situations: Legacy capsules created by old tooling that recorded absolute install paths; hand-edited legacy meta files; a legacy install moved between machines so relative structure no longer holds.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- legacy capsule metadata has no WASM hash
- legacy capsule WIT path is not relative: {}
- capsule source symlink {} resolves outside source root
- legacy capsule directory {id} does not match manifest id {}
- legacy capsule metadata version differs for {id}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/e61ba27cce68c3a4.
Report an issue: GitHub.