astrid-runtime/astrid · error
Distro.toml has no parent directory
Error message
Distro.toml has no parent directory
What it means
Thrown by `resolve_local_capsule_archive` when the local Distro.toml manifest path has no parent directory component, so relative member paths inside the manifest cannot be resolved against a root. In practice this occurs only for degenerate paths like a bare "Distro.toml" reference with no directory portion. Security-relevant relatives: traversal and symlink escapes from this root are checked afterwards and fail closed.
Source
Thrown at crates/astrid-cli/src/commands/distro/local_source.rs:57
/// The returned path is canonicalized so the subsequent copy and hash cover
/// the same filesystem object that passed containment checks.
pub(crate) fn resolve_local_capsule_archive(
source: &str,
manifest_path: Option<&Path>,
) -> anyhow::Result<Option<PathBuf>> {
if !is_local_capsule_source(source) {
return Ok(None);
}
let Some(manifest_path) = manifest_path else {
bail!(
"local capsule source {source:?} requires a local authenticated Distro.toml; \
remote manifests cannot resolve relative members"
);
};
let root = manifest_path
.parent()
.ok_or_else(|| anyhow::anyhow!("Distro.toml has no parent directory"))?;
let source_path = Path::new(source);
let candidate = if source_path.is_absolute() {
source_path.to_path_buf()
} else {
root.join(source_path)
};
if source_path
.components()
.any(|component| matches!(component, Component::ParentDir))
{
bail!("local capsule source {source:?} escapes the authenticated Distro.toml directory");
}
let canonical_root = root
.canonicalize()
.with_context(|| format!("failed to resolve Distro.toml directory {}", root.display()))?;
let canonical_path = candidate
.canonicalize()View on GitHub (pinned to affd8760f4)
Solutions
- Pass the manifest with an explicit directory prefix: `./Distro.toml` instead of `Distro.toml`.
- Use an absolute path to the manifest: `--manifest /path/to/distro/Distro.toml`.
- cd into the manifest's directory and reference it as `./Distro.toml`.
- If constructing the path in code, canonicalize it first (`path.canonicalize()`) so a parent component exists.
Example fix
// before (shell) astrid distro install --manifest Distro.toml // after (shell) astrid distro install --manifest "$PWD/Distro.toml"
Defensive patterns
Strategy: validation
Validate before calling
let manifest = std::path::PathBuf::from(manifest_arg);
let manifest = if manifest.is_relative() {
std::env::current_dir()?.join(manifest)
} else { manifest };
if manifest.parent().is_none() {
return Err(anyhow!("manifest path must include a directory component"));
} Try / catch
match resolve_local_capsule_archive(&manifest, source) {
Err(e) if e.to_string().contains("no parent directory") => {
let abs = std::fs::canonicalize("Distro.toml")?;
resolve_local_capsule_archive(&abs, source)
}
other => other,
} Prevention
- Always pass manifest paths with an explicit `./` prefix or absolute path.
- Canonicalize manifest paths before handing them to distro commands.
- In scripts, use "$PWD/Distro.toml" rather than bare filenames.
- Add a shell-completion/arg validation that rejects bare filenames for --manifest.
When it happens
Trigger: Calling distro install/resolve with a manifest path such as `Distro.toml` (no directory prefix) so `Path::parent()` returns None, and the manifest references relative member archives.
Common situations: Scripting `--manifest Distro.toml` from a working directory where the path was reduced to a bare filename; passing a programmatically constructed PathBuf of just a file name.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- empty archive path
- unsafe archive path '{path}'
- distro source '{source}' must use @owner/repo, a URL, a loca
- capsule source is neither a directory nor a regular file: {}
- {name} not found. Ensure it is installed alongside the astri
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/9f7866e1ecd08676.
Report an issue: GitHub.