astrid-runtime/astrid · error

{} overlaps the Astrid durable root: {} overlaps {}

Error message

{} overlaps the Astrid durable root: {} overlaps {}

What it means

During ASTRID_RUN_DIR validation Astrid canonicalizes both the configured run dir and the durable root (AstridHome root) and rejects the configuration if they are related (one contains the other) or are aliases of each other (e.g. via hardlinks/bind mounts resolving to the same physical path). Run state is disposable while the durable root is not, so colocating them would let runtime cleanup or writes endanger durable data; the error is io::ErrorKind::InvalidData.

Source

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

        },
        Ok(metadata) if !metadata.is_dir() => {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!("{VARIABLE} is not a real directory: {}", path.display()),
            ));
        },
        Ok(_) => {},
        Err(error) if error.kind() == io::ErrorKind::NotFound => {},
        Err(error) => return Err(error),
    }
    crate::platform_fs::verify_no_redirects(&path)?;

    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);

View on GitHub (pinned to affd8760f4)

Solutions

  1. Choose a run dir outside the Astrid home root, e.g. export ASTRID_RUN_DIR=/run/astrid (a tmpfs path is ideal for disposable state)
  2. Check where the durable root lives (home.root(), typically ~/.astrid) and make sure the run dir is neither inside it nor an ancestor of it
  3. If mount aliases are involved, verify with `realpath` / `findmnt` that the two paths resolve to different physical directories

Example fix

// before
export ASTRID_RUN_DIR=$HOME/.astrid/run        # inside durable root
// after
export ASTRID_RUN_DIR=/run/astrid              # outside durable root
Defensive patterns

Strategy: validation

Validate before calling

fn overlaps(a: &std::path::Path, b: &std::path::Path) -> bool {
    let (a, b) = (std::fs::canonicalize(a).unwrap_or(a.into()), std::fs::canonicalize(b).unwrap_or(b.into()));
    a.starts_with(&b) || b.starts_with(&a)
}
// assert !overlaps(run_dir, home_root)

Try / catch

if let Err(e) = astrid_home.validate() {
    if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains("overlaps the Astrid durable root") {
        // choose a run dir outside the durable root and retry
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Setting ASTRID_RUN_DIR to the Astrid home root itself, to a subdirectory or parent of it, or to a different path that canonicalizes/aliases to the same physical directory; triggered via configured_path or validate at startup.

Common situations: Operator sets ASTRID_RUN_DIR=~/.astrid or ~/.astrid/run thinking it is separate; a bind mount or symlink farm makes two apparently different paths resolve to the same physical directory; defaulting ASTRID_RUN_DIR to the home root in scripts.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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