{"record":{"id":"086d50f96f385bd1","repo":"rust-lang/rust-analyzer","slug":"received-response-for-unknown-request","errorCode":null,"errorMessage":"received response for unknown request","messagePattern":"received response for unknown request","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rust-analyzer/src/global_state.rs","lineNumber":604,"sourceCode":"            flycheck: self.flycheck.clone(),\n        }\n    }\n\n    pub(crate) fn send_request<R: lsp_types::Request>(\n        &mut self,\n        params: R::Params,\n        handler: ReqHandler,\n    ) {\n        let request = self.req_queue.outgoing.register(R::METHOD.into(), params, handler);\n        self.send(request.into());\n    }\n\n    pub(crate) fn complete_request(&mut self, response: lsp_server::Response) {\n        let handler = self\n            .req_queue\n            .outgoing\n            .complete(response.id.clone())\n            .expect(\"received response for unknown request\");\n        handler(self, response)\n    }\n\n    pub(crate) fn send_notification<N: lsp_types::Notification>(&self, params: N::Params) {\n        let not = lsp_server::Notification::new(N::METHOD.into(), params);\n        self.send(not.into());\n    }\n\n    pub(crate) fn register_request(\n        &mut self,\n        request: &lsp_server::Request,\n        request_received: Instant,\n    ) {\n        self.req_queue\n            .incoming\n            .register(request.id.clone(), (request.method.clone(), request_received));\n    }\n","sourceCodeStart":586,"sourceCodeEnd":622,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/rust-analyzer/src/global_state.rs#L586-L622","documentation":"complete_request pops the pending-request handler registered when a request was sent to the client, keyed by response id. The .expect panics when a response arrives whose id was never registered (or was already completed/cancelled), meaning the client replied to a request rust-analyzer does not track. This is an internal protocol-queue invariant: every response must match an outstanding request.","triggerScenarios":"A buggy language client sends a response with an id rust-analyzer never issued, sends a duplicate response for the same id (already completed via complete()), or sends a response after the request was handled/cleaned up during a restart or server reload.","commonSituations":"Custom or third-party LSP client implementations, clients that replay buffered responses after a server restart, middleware/proxies that duplicate or re-id messages, and client extensions responding to window/workDoneProgress or apply edits with stale ids.","solutions":["Inspect the client: find what request id it is responding with and why it does not match any outgoing request (enable LSP trace logging of request/response ids).","Update the LSP client/extension to a version that correctly tracks server-issued request ids.","If a proxy or wrapper sits between client and server, ensure it forwards responses verbatim without duplicating or re-numbering ids.","As a workaround, restart the language server to reset the request queue; report the client bug upstream if reproducible."],"exampleFix":"// client-side before: replying with a guessed id\nsend({ id: 0, result: null });\n// after: echo the id from the server's request message\nsend({ id: serverRequest.id, result: computeResult(serverRequest.method) });","handlingStrategy":"validation","validationCode":"// client side: before replying, confirm the id is one you actually received from the server\nif (!pendingServerRequests.has(response.id)) {\n  console.warn('ignoring response for unknown request', response.id);\n  return;\n}\npendingServerRequests.delete(response.id);","typeGuard":"function hasPendingRequest(id: string | number): boolean {\n  return pendingServerRequests.has(id);\n}","tryCatchPattern":null,"preventionTips":["Always echo the exact id from the server's request when responding.","Never send duplicate responses for one request id.","Buffer only responses within a single server session; drop them across restarts.","Enable LSP trace logs to verify id pairing during client development."],"tags":["lsp","protocol","panic","request-queue"],"backgroundTag":"lsp-response-id-mismatch","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}