{"record":{"id":"9be5f78fb0474e61","repo":"astrid-runtime/astrid","slug":"mcp-gateway-rejected-operation","errorCode":null,"errorMessage":"MCP gateway rejected {operation:?}: {}","messagePattern":"MCP gateway rejected (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/mcp/lifecycle.rs","lineNumber":682,"sourceCode":"        .await\n        .context(\"failed to terminate MCP gateway control\")?;\n    write_half\n        .flush()\n        .await\n        .context(\"failed to flush MCP gateway control\")?;\n\n    let mut reader = BufReader::new(read_half);\n    let response = tokio::time::timeout(READY_TIMEOUT, read_bounded_line(&mut reader))\n        .await\n        .context(\"timed out waiting for MCP gateway control acknowledgement\")??;\n    let ack: GatewayControlAck =\n        serde_json::from_slice(&response).context(\"invalid MCP gateway control acknowledgement\")?;\n    if ack.version != GATEWAY_CONTROL_VERSION || ack.operation != operation || ack.pid != record.pid\n    {\n        anyhow::bail!(\"MCP gateway returned an unbound control acknowledgement\");\n    }\n    if !ack.ok {\n        anyhow::bail!(\n            \"MCP gateway rejected {operation:?}: {}\",\n            ack.error.as_deref().unwrap_or(\"unknown gateway failure\")\n        );\n    }\n    Ok(ack)\n}\n\npub(crate) async fn read_bounded_line<R>(reader: &mut R) -> Result<Vec<u8>>\nwhere\n    R: tokio::io::AsyncRead + Unpin,\n{\n    let mut line = Vec::new();\n    for _ in 0..=MAX_CONTROL_BYTES {\n        let byte = reader\n            .read_u8()\n            .await\n            .context(\"failed to read control frame\")?;\n        if byte == b'\\n' {","sourceCodeStart":664,"sourceCodeEnd":700,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/mcp/lifecycle.rs#L664-L700","documentation":"The gateway accepted the control request but responded with ack.ok = false; the error carries the operation name and the gateway's error string (or 'unknown gateway failure'). This is the gateway-side failure surfacing through the control protocol.","triggerScenarios":"Any control operation (e.g. shutdown/restart requested via request_gateway_control by wait_for_gateway or stop_ready_gateway) where the gateway sets ok=false in its GatewayControlAck.","commonSituations":"Gateway busy or shutting down while asked to stop; internal gateway error performing the operation; mismatched gateway build that doesn't implement the requested operation and reports failure.","solutions":["Read the gateway's error text in the message to identify the gateway-side cause","Retry the operation once the gateway is idle, or restart the gateway entirely","Check gateway logs for the corresponding failure around the same timestamp","Verify CLI/gateway version compatibility if the operation is reported unknown"],"exampleFix":"// before\nlet ack = request_gateway_control(...).await?;\n// after: handle gateway-side rejection\nmatch request_gateway_control(...).await {\n    Err(e) if e.to_string().contains(\"MCP gateway rejected\") => {\n        eprintln!(\"gateway refused: {e}; retrying after restart\");\n        restart_gateway().await?;\n    },\n    other => other?,\n}","handlingStrategy":"try-catch","validationCode":"// ensure gateway is healthy before issuing control ops\nlet health = ping_gateway(&gateway_socket_path()?).await;\nanyhow::ensure!(health.is_ok(), \"gateway unhealthy; restart before control ops\");","typeGuard":null,"tryCatchPattern":"match request_gateway_control(...).await {\n    Err(e) if e.to_string().contains(\"MCP gateway rejected\") => {\n        eprintln!(\"gateway refused operation: {e}\");\n        // parse gateway error text and decide: retry vs restart\n    },\n    other => other?,\n}","preventionTips":["Read the gateway's embedded error string before retrying","Monitor gateway logs alongside CLI operations","Keep gateway and CLI versions compatible"],"tags":["ipc","gateway","protocol-error"],"backgroundTag":"api-error-response","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}