astrid-runtime/astrid · error
MCP gateway lock path has no parent
Error message
MCP gateway lock path has no parent
What it means
`open_lock_file` computes the parent directory of the lock-file path to create it with private (0600/0700) permissions. `Path::parent()` returns `None` only for paths with no directory component (e.g. a bare root). This error is an internal invariant guard: the gateway lock path is always derived from the runtime home, so hitting it means the path construction was corrupted.
Source
Thrown at crates/astrid-cli/src/commands/mcp/lifecycle.rs:99
#[derive(Debug)]
pub(crate) struct GatewaySupervisorLock(std::fs::File);
impl GatewayLifecycleLock {
pub(crate) const fn file(&self) -> &std::fs::File {
&self.0
}
}
impl GatewaySupervisorLock {
pub(crate) const fn file(&self) -> &std::fs::File {
&self.0
}
}
fn open_lock_file(path: &Path) -> Result<std::fs::File> {
let parent = path
.parent()
.ok_or_else(|| anyhow::anyhow!("MCP gateway lock path has no parent"))?;
ensure_private_dir(parent)?;
let mut options = std::fs::OpenOptions::new();
options.read(true).write(true).create(true).truncate(false);
#[cfg(unix)]
{
use std::os::unix::fs::OpenOptionsExt as _;
options.mode(0o600);
}
options
.open(path)
.with_context(|| format!("failed to open {}", path.display()))
}
fn try_lock_file(file: std::fs::File, path: &Path) -> Result<Option<std::fs::File>> {
match file.try_lock() {
Ok(()) => Ok(Some(file)),
Err(std::fs::TryLockError::WouldBlock) => Ok(None),
Err(std::fs::TryLockError::Error(error)) => {View on GitHub (pinned to affd8760f4)
Solutions
- Check the runtime home / state directory configuration; it must be a normal directory path, not `/` or empty.
- Report as a bug if the path was constructed by the library itself with default configuration.
- Run with default settings (no home/path overrides) to confirm the error disappears.
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) = open_lock_file(&path) {
if e.to_string().contains("has no parent") {
eprintln!("misconfigured lock path: {}", path.display());
}
return Err(e);
} Prevention
- Never point the runtime home at `/` or an empty value
- Let the library derive lifecycle paths from its default home
- Validate path overrides at startup
- Report occurrences with default config as bugs
When it happens
Trigger: Essentially only when the lock path is misconstructed to a bare filename or filesystem root, e.g. a runtime home directory configured to `/` or empty, causing `gateway lock path` to resolve without a parent directory.
Common situations: A misconfigured environment/runtime home pointing at `/`; a bug or unusual override producing a root-relative lock path. Practically unreachable with normal installation layouts.
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
- MCP gateway startup lease path has no parent
- MCP gateway readiness path has no parent
- MCP gateway socket path has no parent
- invalid MCP gateway startup lease at {}
- MCP gateway startup generation changed before cleanup
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/9487ef7d954fbefb.
Report an issue: GitHub.