astrid-runtime/astrid · error
legacy capsule WIT path is not relative: {}
Error message
legacy capsule WIT path is not relative: {} What it means
Raised by canonical_legacy_archive when migrating a legacy native capsule: a WIT file's path, computed relative to the legacy home directory, contains a parent-directory (..) or root (/) component. The library refuses to place non-relative paths into the staging archive because they could escape the staging directory or produce an invalid package layout. This is a path-safety check during legacy capsule migration.
Source
Thrown at crates/astrid-capsule-install/src/storage.rs:676
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!(
part,
std::path::Component::ParentDir | std::path::Component::RootDir
)
})
{
bail!(
"legacy capsule WIT path is not relative: {}",
relative.display()
);
}
let source = home.wit_store_dir().join(format!("{hash}.wit"));
let destination = staging.path().join("wit").join(relative);
if let Some(parent) = destination.parent() {
fs::create_dir_all(parent)?;
}
fs::copy(&source, &destination)
.with_context(|| format!("restore content-addressed WIT blob {hash}"))?;
}
canonical_capsule_archive(staging.path())
}
fn copy_legacy_tree(source: &Path, destination: &Path) -> anyhow::Result<()> {
fs::create_dir_all(destination)?;
for (path, metadata) in read_dir_sorted(source)? {View on GitHub (pinned to affd8760f4)
Solutions
- Inspect the legacy capsule's WIT store metadata and fix the recorded path so it is relative to the legacy home directory (no leading `/`, no `..` segments).
- Reinstall or re-publish the affected WIT package into the legacy capsule so the store entry is regenerated with a canonical relative path.
- If the legacy state is corrupt, remove the affected legacy capsule and migrate it fresh from its original source.
Example fix
// before: legacy metadata stores an absolute WIT path "wit_path": "/home/alice/.astrid/wit/abc123.wit" // after: store path relative to the legacy home/wit store root "wit_path": "abc123.wit"
Defensive patterns
Strategy: validation
Validate before calling
fn wit_path_is_relative(p: &Path) -> bool {
!p.is_absolute()
&& p.components().all(|c| matches!(c, std::path::Component::Normal(_)))
} Type guard
fn is_clean_relative(p: &Path) -> bool {
p.is_relative() && !p.components().any(|c| c.as_os_str() == "..")
} Try / catch
match migrate_native_capsules_with_report(...) {
Err(e) if e.to_string().contains("not relative") => fix_legacy_wit_paths(),
other => other?,
} Prevention
- Never hand-edit legacy WIT store metadata
- Store WIT paths relative to the wit store root
- Validate legacy capsule state before running migrations
When it happens
Trigger: Calling migrate_native_capsules_with_report on a legacy capsule whose wit_store metadata or recorded relative WIT path contains `..`, is absolute, or otherwise fails the relative-path component check; typically from tampered or hand-edited legacy metadata rather than normal installs.
Common situations: Legacy capsule state directories copied between machines with altered layout; manually edited or corrupted legacy WIT store entries; migration scripts that rewrote paths with absolute prefixes or `..` segments.
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 component path is not relative
- legacy capsule metadata has no WASM hash
- capsule path is not canonical: {path}
- legacy capsule directory is not a regular directory: {}
- legacy capsule entry is not a regular directory: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/56226fe4d2766234.
Report an issue: GitHub.