astrid-runtime/astrid · error · std::io::Error::InvalidInput
{var_name} must not contain '..' path components
Error message
{var_name} must not contain '..' path components What it means
Thrown by reject_parent_traversal when a path configured via an environment variable contains '..' parent-directory components. This blocks path-traversal attacks and accidental escapes from the intended Astrid home directory.
Source
Thrown at crates/astrid-core/src/dirs.rs:228
#[error("workspace state directory name must not contain path separators")]
Separator,
/// The name contains a non-portable character.
#[error(
"workspace state directory name may contain only ASCII letters, digits, '.', '_', and '-'"
)]
InvalidCharacter,
/// The name exceeds the portable length bound.
#[error("workspace state directory name must be at most 64 bytes")]
TooLong,
/// The name is reserved by a supported filesystem.
#[error("workspace state directory name is reserved: {0:?}")]
Reserved(String),
}
/// Reject paths containing `..` (parent directory) components.
fn reject_parent_traversal(path: &Path, var_name: &str) -> io::Result<()> {
if path.components().any(|c| matches!(c, Component::ParentDir)) {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("{var_name} must not contain '..' path components"),
));
}
Ok(())
}
// ── AstridHome (system-level) ────────────────────────────────────────────
/// Global Astrid home directory (`~/.astrid/`, Windows `LocalAppData`, or
/// `$ASTRID_HOME`).
///
/// FHS-aligned system layout with config (`etc/`), persistent state (`var/`),
/// runtime (`run/`), logs (`log/`), keys (`keys/`), and shared modules (`lib/`).
/// Principal content is authoritative in `AstridFilesystem`; native `home/` is
/// retained only as a legacy migration source.
#[derive(Debug, Clone)]
pub struct AstridHome {View on GitHub (pinned to affd8760f4)
Solutions
- Remove '..' segments from the ASTRID_HOME value and use a clean absolute path
- Re-export ASTRID_HOME with a canonicalized path (e.g. via realpath)
Example fix
// before export ASTRID_HOME=/home/user/.astrid/../shared // after export ASTRID_HOME=/home/user/shared
Defensive patterns
Strategy: validation
Validate before calling
fn is_safe(p: &str) -> bool {
let pb = std::path::PathBuf::from(p);
pb.is_absolute() && !pb.components().any(|c| matches!(c, std::path::Component::ParentDir))
}
assert!(is_safe(&astrid_home)); Type guard
fn safe_env_path(v: &str) -> Option<std::path::PathBuf> {
let p = std::path::PathBuf::from(v);
(p.is_absolute()
&& !p.components().any(|c| matches!(c, std::path::Component::ParentDir)))
.then_some(p)
} Try / catch
match result {
Err(e) if e.kind() == io::ErrorKind::InvalidInput && e.to_string().contains("'..'") => {
eprintln!("Fix the env var: remove '..' components");
},
other => other?,
} Prevention
- Set env paths via canonicalized absolute values
- Never include '..' in configuration paths
- Lint shell rc files for dot-dot path exports
When it happens
Trigger: Calling resolve_with_env with ASTRID_HOME (or HOME) set to a value like '/home/user/.astrid/../evil' or '~/..'; reject_parent_traversal scans Path components for Component::ParentDir.
Common situations: Shell config exporting a relative or dot-dot-containing ASTRID_HOME, copy-pasted paths with '..' segments, or malicious environment in untrusted contexts.
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
- git history path must be a relative in-repository path
- ASTRID_HOME must be an absolute path
- HOME must be an absolute path
- sandbox {label} contains forbidden characters (double-quote,
- manifest exceeds its installed capability approval: {details
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/f6330927303799ad.
Report an issue: GitHub.