astrid-runtime/astrid · error

{VARIABLE} {detail}

Error message

{VARIABLE} {detail}

What it means

Astrid validates the ASTRID_RUN_DIR environment variable before using it and rejects malformed values with io::ErrorKind::InvalidInput. The message is `{VARIABLE} {detail}` where VARIABLE is the literal env var name; known details include: the value must not be empty, must be an absolute path, and must not contain '.' or '..' path components.

Source

Thrown at crates/astrid-core/src/dirs_run_dir.rs:73

    let physical_run = physical_path(&path)?;
    let physical_root = physical_path(home.root())?;
    if paths_are_related(&physical_run, &physical_root)
        || directories_are_aliases(&physical_run, &physical_root)
    {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "{VARIABLE} overlaps the Astrid durable root: {} overlaps {}",
                path.display(),
                home.root().display()
            ),
        ));
    }
    Ok(Some(physical_run))
}

fn invalid(detail: &str) -> io::Error {
    io::Error::new(io::ErrorKind::InvalidInput, format!("{VARIABLE} {detail}"))
}

fn physical_path(path: &Path) -> io::Result<PathBuf> {
    if let Ok(physical) = std::fs::canonicalize(path) {
        return Ok(physical);
    }
    let mut missing = Vec::new();
    let mut existing_parent = path;
    while matches!(
        std::fs::symlink_metadata(existing_parent),
        Err(error) if error.kind() == io::ErrorKind::NotFound
    ) {
        let Some(name) = existing_parent.file_name() else {
            break;
        };
        missing.push(name.to_os_string());
        existing_parent = existing_parent.parent().expect("parent checked above");
    }

View on GitHub (pinned to affd8760f4)

Solutions

  1. Set ASTRID_RUN_DIR to a non-empty, absolute path with no '.' or '..' components, e.g. /run/astrid
  2. Normalize the value in your deploy config: resolve variables before export (`export ASTRID_RUN_DIR="$(realpath -m "$BASE/run")"`) and guard against empty expansion
  3. Unset ASTRID_RUN_DIR entirely to use the default (home root + `run`) if you do not need a custom location

Example fix

// before
export ASTRID_RUN_DIR=astrid/run/../tmp   # relative + '..'
// after
export ASTRID_RUN_DIR=/var/run/astrid     # absolute, clean components
Defensive patterns

Strategy: validation

Validate before calling

fn run_dir_value_ok(raw: &std::ffi::OsStr) -> bool {
    let p = std::path::PathBuf::from(raw);
    !raw.is_empty() && p.is_absolute()
        && !p.components().any(|c| matches!(c, std::path::Component::ParentDir | std::path::Component::CurDir))
}

Try / catch

match std::env::var_os("ASTRID_RUN_DIR") {
    Some(v) if !run_dir_value_ok(&v) => {
        eprintln!("ASTRID_RUN_DIR must be a non-empty absolute path without '.'/'..'; using default");
        std::env::remove_var("ASTRID_RUN_DIR");
    },
    _ => {},
}

Prevention

When it happens

Trigger: ASTRID_RUN_DIR set to an empty string; set to a relative path like `run` or `./run`; or containing `.`/`..` components such as /var/run/../astrid. Raised by the `invalid` helper inside `resolved`, called from configured_path/validate at startup.

Common situations: Shell exports ASTRID_RUN_DIR='' (e.g. `export ASTRID_RUN_DIR=;` or unexpanded variable); Docker/K8s env uses a relative path; a templated config produces /var/lib/../run/astrid.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/3da2c1f0a31f8579. Report an issue: GitHub.