{"record":{"id":"695fd0ef8c759fbe","repo":"rust-lang/rust","slug":"proc-macro-server-did-not-respond-with-data","errorCode":null,"errorMessage":"proc-macro server did not respond with data","messagePattern":"proc-macro server did not respond with data","errorType":"exception","errorClass":"ServerError","httpStatus":null,"severity":"error","filePath":"src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs","lineNumber":332,"sourceCode":"        result\n    }\n\n    pub(crate) fn send_task_legacy<Request, Response>(\n        &self,\n        send: impl FnOnce(\n            &mut dyn Write,\n            &mut dyn BufRead,\n            Request,\n            &mut String,\n        ) -> Result<Option<Response>, ServerError>,\n        req: Request,\n    ) -> Result<Response, ServerError> {\n        self.with_locked_io(String::new(), |writer, reader, buf| {\n            send(writer, reader, req, buf).and_then(|res| {\n                res.ok_or_else(|| {\n                    let message = \"proc-macro server did not respond with data\".to_owned();\n                    ServerError {\n                        io: Some(Arc::new(io::Error::new(\n                            io::ErrorKind::BrokenPipe,\n                            message.clone(),\n                        ))),\n                        message,\n                    }\n                })\n            })\n        })\n    }\n\n    fn with_locked_io<R, B>(\n        &self,\n        mut buf: B,\n        f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut B) -> Result<R, ServerError>,\n    ) -> Result<R, ServerError> {\n        let state = &mut *self.state.lock().unwrap();\n        f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| {\n            if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) {","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs#L314-L350","documentation":"Returned by rust-analyzer's legacy (JSON) proc-macro IPC path send_task_legacy when the server responds with None instead of a Response. This means the proc-macro server accepted the request but produced no data - the wrapper synthesizes a BrokenPipe io::Error and the ServerError 'proc-macro server did not respond with data'. with_locked_io later upgrades this to the server's exit error if the process has terminated.","triggerScenarios":"A proc-macro expansion request over the legacy JSON protocol where the server closes stdout or returns an empty/partial frame - e.g. proc-macro-srv crashed, was killed, hit a fatal error, or the protocol got out of sync. Triggered when rust-analyzer has not negotiated the bidirectional protocol.","commonSituations":"proc-macro-srv binary missing or wrong version; proc-macro crate failing to compile/load inside the server; antivirus terminating the child; large/hung macro exhausting the server.","solutions":["Verify the proc-macro-srv binary rust-analyzer spawns exists and matches the toolchain.","Inspect proc-macro-srv output/stderr for crashes or load failures of the target crate.","Try the bidirectional protocol (proc-macro server setting) if available, which gives richer error context.","Disable proc-macro expansion for the problematic crate to restore IDE function."],"exampleFix":"// runtime/IDE configuration fix, not source code.\n// In rust-analyzer settings, point to the correct server:\n//   \"procMacro.server\": \"/path/to/proc-macro-srv\"\n// or build it from the same source tree: cargo build -p proc-macro-srv-cli","handlingStrategy":"try-catch","validationCode":"// Before sending, confirm the server process is still running:\n// if server.child.try_wait()?.is_some() { return Err(\"server gone\"); }","typeGuard":null,"tryCatchPattern":"match send_task_legacy(send, req) {\n    Ok(r) => Ok(r),\n    Err(ServerError { io: Some(ref i), .. })\n        if i.kind() == io::ErrorKind::BrokenPipe => {\n        // server exited; surface exit_err, disable expansion\n        Err(\"proc-macro server exited without data\".into())\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Use the bidirectional protocol when available for richer errors.","Point rust-analyzer at a proc-macro-srv built from the same source.","Disable proc-macro expansion for crates that crash the server."],"tags":["rust-analyzer","proc-macro","ipc","protocol","broken-pipe"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}