astrid-runtime/astrid · error

MCP gateway readiness path has no parent

Error message

MCP gateway readiness path has no parent

What it means

`write_gateway_ready` publishes readiness metadata atomically (temp file + rename) only after the gateway has authenticated and bound its listener. This error is thrown when the readiness file path has no parent directory — an invariant guard, since the ready path always derives from the runtime home directory in normal operation.

Source

Thrown at crates/astrid-cli/src/commands/mcp/lifecycle.rs:325

    if record.version != 1
        || record.pid == 0
        || record.principal.is_empty()
        || record.hook_token.is_empty()
    {
        anyhow::bail!(
            "invalid MCP gateway readiness metadata at {}",
            path.display()
        );
    }
    Ok(Some(record))
}

/// Write readiness metadata without exposing a partial record to attachers.
pub(crate) fn write_gateway_ready(record: &GatewayReady) -> Result<()> {
    let path = gateway_ready_path()?;
    let parent = path
        .parent()
        .ok_or_else(|| anyhow::anyhow!("MCP gateway readiness path has no parent"))?;
    ensure_private_dir(parent)?;
    let temp = path.with_extension(format!("ready.tmp.{}", std::process::id()));
    let bytes = serde_json::to_vec(record).context("failed to encode MCP gateway readiness")?;
    std::fs::write(&temp, bytes).with_context(|| format!("failed to write {}", temp.display()))?;
    #[cfg(unix)]
    {
        use std::os::unix::fs::PermissionsExt;
        std::fs::set_permissions(&temp, std::fs::Permissions::from_mode(0o600))?;
    }
    std::fs::rename(&temp, &path)
        .with_context(|| format!("failed to publish {}", path.display()))?;
    Ok(())
}

/// Remove this gateway's readiness marker without deleting a successor's.
pub(crate) fn remove_gateway_ready(record: &GatewayReady) -> Result<()> {
    let path = gateway_ready_path()?;
    remove_gateway_ready_at(&path, record)

View on GitHub (pinned to affd8760f4)

Solutions

  1. Correct the runtime home / state directory configuration.
  2. Rerun with default settings to bypass any bad override.
  3. File a bug if it occurs with default configuration.

Example fix

// before
ASTRID_RUNTIME_HOME=/ astrid mcp gateway run
// after
ASTRID_RUNTIME_HOME=$HOME/.local/share/astrid astrid mcp gateway run
Defensive patterns

Strategy: validation

Validate before calling

let home = std::env::var("ASTRID_RUNTIME_HOME").unwrap_or_default();
assert!(home != "/" && !home.is_empty(), "runtime home must be a normal directory");

Type guard

fn has_parent(p: &std::path::Path) -> bool { p.parent().is_some() }

Try / catch

if let Err(e) = write_gateway_ready(&record) {
    if e.to_string().contains("has no parent") {
        eprintln!("bad readiness path configuration");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: The readiness path (`mcp-gateway.ready`) resolves without a parent directory, i.e. the runtime home/state root is `/` or empty, or the path was misconstructed by the library.

Common situations: Misconfigured runtime home pointing at the filesystem root; corrupted path derivation. Effectively unreachable with default configuration.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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