astrid-runtime/astrid · error

returned a relative or traversing native mountpoint

Error message

{provider_name} returned a relative or traversing native mountpoint: {}

What it means

validate_response_mountpoint sanitizes mountpoint paths returned by native providers. The path must be absolute and must not contain ParentDir (..) or CurDir (.) components. Otherwise a malicious or buggy provider could point the CLI at an arbitrary or traversing filesystem location, so the CLI bails.

Solutions

  1. Fix the provider to return a canonical, absolute mountpoint path (e.g. via fs::canonicalize before responding)
  2. Ensure the provider's CWD doesn't influence mountpoint resolution
  3. If you control the mount location, mount under a fixed absolute root directory
  4. Report the provider as misbehaving/compromised if traversal appears intentional

Example fix

// before (provider)
mountpoint: PathBuf::from("../mnt/astrid"),
// after
mountpoint: std::fs::canonicalize("/mnt/astrid")?,
Defensive patterns

Strategy: validation

Validate before calling

fn mountpoint_safe(p: &std::path::Path) -> bool { p.is_absolute() && !p.components().any(|c| matches!(c, std::path::Component::ParentDir | std::path::Component::CurDir)) }

Type guard

fn trusted_mountpoint(p: &Path) -> Option<&Path> { if mountpoint_safe(p) { Some(p) } else { None } }

Try / catch

if !mountpoint_safe(&mountpoint) {
    eprintln!("refusing unsafe mountpoint from provider: {}", mountpoint.display());
    return Ok(ExitCode::FAILURE);
}

Prevention

When it happens

Trigger: A Mounted/Status success outcome carries a mountpoint that is relative, or contains '..'/'.' path components — checked via std::path::Component inspection in validate_response_mountpoint, called from validate_response.

Common situations: Provider returns a relative path because it resolved the mountpoint against its own CWD; a compromised provider attempts a path-traversal to place a mount outside allowed roots; a provider on a different OS returns a path with components the CLI doesn't accept.

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


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

Appendix: source

Thrown at crates/astrid-cli/src/commands/storage.rs:276

    match &response.outcome {
        StorageProviderOutcomeV1::Success(
            StorageProviderSuccessV1::Mounted { mountpoint, .. }
            | StorageProviderSuccessV1::Status { mountpoint, .. },
        ) => validate_response_mountpoint(provider_name, mountpoint),
        _ => Ok(()),
    }
}

fn validate_response_mountpoint(provider_name: &str, mountpoint: &Path) -> Result<()> {
    if !mountpoint.is_absolute()
        || mountpoint.components().any(|component| {
            matches!(
                component,
                std::path::Component::ParentDir | std::path::Component::CurDir
            )
        })
    {
        bail!(
            "{provider_name} returned a relative or traversing native mountpoint: {}",
            mountpoint.display()
        );
    }
    Ok(())
}

fn capabilities_are_unique(capabilities: &[StorageProviderCapabilityV1]) -> bool {
    let mut admitted = Vec::with_capacity(capabilities.len());
    for capability in capabilities {
        if admitted.contains(capability) {
            return false;
        }
        admitted.push(*capability);
    }
    true
}

View on GitHub (pinned to affd8760f4)