{"record":{"id":"7b7f29bbdff84d3f","repo":"astrid-runtime/astrid","slug":"mcp-gateway-control-frame-is-missing-or-too-large","errorCode":null,"errorMessage":"MCP gateway control frame is missing or too large","messagePattern":"MCP gateway control frame is missing or too large","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/mcp/lifecycle.rs","lineNumber":705,"sourceCode":"    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' {\n            return Ok(line);\n        }\n        line.push(byte);\n    }\n    anyhow::bail!(\"MCP gateway control frame is missing or too large\")\n}\n\nasync fn remove_dead_gateway_markers(record: &GatewayReady) -> Result<()> {\n    if crate::commands::daemon_control::is_process_alive(record.pid) {\n        anyhow::bail!(\n            \"shutdown stage gateway.process_reap: PID {} is still alive\",\n            record.pid\n        );\n    }\n    let lifecycle = try_acquire_gateway_lifecycle()?;\n    let Some(lifecycle) = lifecycle else {\n        anyhow::bail!(\n            \"shutdown stage gateway.lifecycle_fence: a successor gateway lifecycle remains active\"\n        );\n    };\n    let socket = gateway_socket_path()?;\n    match astrid_core::local_transport::connect_outcome(&socket)\n        .await","sourceCodeStart":687,"sourceCodeEnd":723,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/mcp/lifecycle.rs#L687-L723","documentation":"read_bounded_line reads the control-frame bytes until a newline or its size bound; if neither the terminating \\n nor the bound is reached (stream ended early or frame exceeded the limit without delimiter), it bails with this message.","triggerScenarios":"The gateway closes the control connection before sending a newline, or sends a frame larger than the bounded limit without a delimiter, while request_gateway_control reads the ack.","commonSituations":"Gateway crashed mid-response; a non-gateway process or error text wrote to the socket; a protocol mismatch producing an oversized undelimited blob.","solutions":["Restart the gateway and retry the control operation — the stream likely died mid-frame","Check gateway logs for a crash or panic around the request time","Confirm nothing else is writing to the gateway socket (stale listener, another process)","If frames legitimately grow, raise the frame size bound in the client and gateway together"],"exampleFix":"// before: single attempt\nlet ack = request_gateway_control(...).await?;\n// after: retry once on truncated frame\nlet ack = match request_gateway_control(...).await {\n    Err(e) if e.to_string().contains(\"missing or too large\") => {\n        restart_gateway().await?;\n        request_gateway_control(...).await?\n    },\n    other => other?,\n};","handlingStrategy":"retry","validationCode":"// verify the socket answers before sending control frames\nlet outcome = connect_outcome(&gateway_socket_path()?).await?;\nanyhow::ensure!(!matches!(outcome, ConnectOutcome::Absent), \"gateway socket absent\");","typeGuard":null,"tryCatchPattern":"match request_gateway_control(...).await {\n    Err(e) if e.to_string().contains(\"missing or too large\") => {\n        restart_gateway().await?;\n        request_gateway_control(...).await?\n    },\n    other => other?,\n}","preventionTips":["Check gateway logs for crashes producing truncated frames","Don't point the client at a socket written by a different process","Keep frame-size bounds identical on client and gateway"],"tags":["ipc","protocol","truncated-response"],"backgroundTag":"invalid-json-response","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}