astrid-runtime/astrid · error
MCP gateway is already bound to principal
Error message
MCP gateway is already bound to principal '{}', not '{}' What it means
Fired by wait_for_gateway when a ready gateway is reachable but its ready record is bound to a different principal than the one requesting attachment. Gateways are single-principal; attaching another principal's client would cross trust boundaries.
Solutions
- Connect as the principal the gateway was started for
- Stop the current gateway and start one under the desired principal
- Run separate gateways per principal if isolation is needed
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/astrid-cli/src/commands/mcp/lifecycle.rs:413 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/8b48b2e4e393ae11.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/mcp/lifecycle.rs:413
}
Ok(path)
}
/// Wait for a ready gateway, starting one child at most once when absent.
pub(crate) async fn wait_for_gateway(principal: &PrincipalId, format: &str) -> Result<ExitCode> {
let format = ReadyFormat::parse(format)?;
let socket = gateway_socket_path()?;
let deadline = Instant::now()
.checked_add(SPAWNED_READY_TIMEOUT)
.unwrap_or_else(Instant::now);
let mut spawned = false;
loop {
if let Some(record) = read_gateway_ready()? {
// A gateway is bound to the principal that minted its ready
// record. Each attach must present that same process principal
// and the gateway's token before an uplink is selected.
if record.principal != principal.to_string() {
anyhow::bail!(
"MCP gateway is already bound to principal '{}', not '{}'",
record.principal,
principal
);
}
match astrid_core::local_transport::connect_outcome(&socket)
.await
.context("failed to inspect MCP gateway endpoint")?
{
astrid_core::local_transport::ConnectOutcome::Connected(stream) => {
request_gateway_control(stream, &record, GatewayControlOperation::Health)
.await
.context("MCP gateway cannot prove a recoverable daemon uplink")?;
emit_ready(format, &record)?;
return Ok(ExitCode::SUCCESS);
},
astrid_core::local_transport::ConnectOutcome::Absent
| astrid_core::local_transport::ConnectOutcome::StaleView on GitHub (pinned to affd8760f4)