astrid-runtime/astrid · error
legacy capsule entry is not a regular directory: {}
Error message
legacy capsule entry is not a regular directory: {} What it means
While enumerating children of the legacy native capsule directory, each entry must be a regular directory representing one capsule. If an entry is a symlink or a non-directory file, migration stops with this error rather than guessing how to migrate it.
Source
Thrown at crates/astrid-capsule-install/src/storage/migration.rs:122
return Ok(LegacyCapsuleMigrationReport::default());
},
Err(error) => return Err(error).with_context(|| format!("inspect {}", native.display())),
};
if metadata.file_type().is_symlink() || !metadata.is_dir() {
bail!(
"legacy capsule directory is not a regular directory: {}",
native.display()
);
}
astrid_core::platform_fs::verify_no_redirects(&native)
.with_context(|| format!("verify legacy capsule root {}", native.display()))?;
let mut children = read_dir_sorted(&native)?;
let mut report = LegacyCapsuleMigrationReport::default();
let registry = store.capsules();
let owner = StateOwner::Principal(uid);
for (target, target_metadata) in children.drain(..) {
if target_metadata.file_type().is_symlink() || !target_metadata.is_dir() {
bail!(
"legacy capsule entry is not a regular directory: {}",
target.display()
);
}
let id = target
.file_name()
.and_then(|name| name.to_str())
.ok_or_else(|| anyhow::anyhow!("legacy capsule entry has a non-UTF-8 name"))?;
let manifest = astrid_capsule::discovery::load_manifest(&target.join("Capsule.toml"))
.with_context(|| format!("read legacy capsule manifest {id}"))?;
if manifest.package.name != id {
bail!(
"legacy capsule directory {id} does not match manifest id {}",
manifest.package.name
);
}
let meta_bytes = fs::read(target.join("meta.json"))
.with_context(|| format!("read legacy capsule metadata {id}"))?;View on GitHub (pinned to affd8760f4)
Solutions
- Remove the symlink or stray file from the legacy capsules directory
- Move the real capsule directory to the expected location instead of linking it
- Delete broken/incomplete capsule entries that are not valid directories
- Run migration again after the capsules root contains only regular directories
Example fix
# before ~/.astrid/native/my-capsule -> ~/dev/my-capsule (symlink) # after cp -a ~/dev/my-capsule ~/.astrid/native/my-capsule # real directory
Defensive patterns
Strategy: validation
Validate before calling
fn capsules_root_clean(p: &Path) -> Result<(), String> {
for entry in std::fs::read_dir(p).map_err(|e| e.to_string())? {
let e = entry.map_err(|e| e.to_string())?;
let ft = e.file_type().map_err(|e| e.to_string())?;
if ft.is_symlink() || !ft.is_dir() {
return Err(format!("{} is not a regular directory", e.path().display()));
}
}
Ok(())
} Type guard
fn is_regular_dir_entry(p: &std::path::Path) -> bool {
std::fs::symlink_metadata(p)
.map(|md| md.is_dir() && !md.file_type().is_symlink())
.unwrap_or(false)
} Try / catch
if let Err(e) = migrate_native_capsules(home, store) {
if e.to_string().contains("entry is not a regular directory") {
eprintln!("remove symlinks/stray files from the capsules directory, then retry");
} else { return Err(e); }
} Prevention
- Never symlink individual capsules into the installed capsules directory
- Keep loose files (archives, notes) out of the capsules root
- Clean broken/partial installs before migrating
- Inspect the capsules directory with ls -la before migrating
When it happens
Trigger: A symlink inside the native capsules directory (e.g. one capsule symlinked to a dev checkout), or a stray file (log, .DS_Store-like artifact, tarball) sitting directly in the capsules root.
Common situations: Developers symlink their in-development capsule into the installed capsules directory; downloads or editors leave loose files in the capsules root; corrupted partial installs.
Related errors
- legacy capsule directory is not a regular directory: {}
- legacy audit source is not a regular directory: {}
- capsule materialization target is redirected or not a direct
- legacy REPL history is not a regular file: {}
- layout migration destination is redirected or not a regular
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/496619554644f538.
Report an issue: GitHub.