astrid-runtime/astrid · error

MCP attach workspace must be absolute: {value}

Error message

MCP attach workspace must be absolute: {value}

What it means

validate_workspace requires the workspace path to be absolute because the gateway may resolve it independently of the client's working directory. Relative paths are ambiguous across the client/gateway process boundary, so they are rejected with the offending value in the message. After the absolute check, the path is canonicalized to its real location.

Source

Thrown at crates/astrid-cli/src/commands/mcp/gateway.rs:976

fn mint_hook_token() -> String {
    format!(
        "{}{}",
        Uuid::new_v4().as_simple(),
        Uuid::new_v4().as_simple()
    )
}

fn mint_boot_token() -> String {
    Uuid::new_v4().as_simple().to_string()
}

fn validate_workspace(value: &str) -> Result<PathBuf> {
    if value.is_empty() {
        anyhow::bail!("MCP attach workspace is empty");
    }
    let path = PathBuf::from(value);
    if !path.is_absolute() {
        anyhow::bail!("MCP attach workspace must be absolute: {value}");
    }
    std::fs::canonicalize(&path)
        .with_context(|| format!("failed to resolve MCP attach workspace {value}"))
}

fn set_socket_mode(path: &Path) -> Result<()> {
    #[cfg(unix)]
    {
        use std::os::unix::fs::PermissionsExt;
        std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o600))?;
    }
    Ok(())
}

#[cfg(test)]
#[path = "gateway_tests.rs"]
mod tests;

View on GitHub (pinned to affd8760f4)

Solutions

  1. Convert the workspace to an absolute path (fs::canonicalize or cwd.join) before sending the registration
  2. Expand ~/ in config before storing it (e.g. with the dirs/home_dir crates)
  3. Use the absolute path returned by a prior canonicalize when building the registration
  4. Ensure the directory exists so canonicalize also succeeds

Example fix

// before
workspace_abs: "~/projects/app".into(),
// after
let base = dirs::home_dir().context("no home dir")?;
workspace_abs: base.join("projects/app").canonicalize()?.display().to_string(),
Defensive patterns

Strategy: validation

Validate before calling

let p = PathBuf::from(&reg.workspace_abs);
if !p.is_absolute() { return Err(format!("workspace must be absolute, got {}", reg.workspace_abs)); }
let canonical = std::fs::canonicalize(&p)?;

Type guard

fn is_absolute_workspace(p: &str) -> bool { PathBuf::from(p).is_absolute() }

Prevention

When it happens

Trigger: Attach registration workspace_abs is a relative path like "myproject" or "."; workspace built by joining without a base; tilde paths like "~/proj" that were never expanded.

Common situations: Client run from a different cwd than the gateway; shell tilde not expanded in config; user entered a project name instead of a full path in settings.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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