{"id":"f379a80f1bd08111","repo":"actix/actix-web","slug":"cannot-reuse-response-builder","errorCode":null,"errorMessage":"cannot reuse response builder","messagePattern":"cannot reuse response builder","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"actix-web/src/response/builder.rs","lineNumber":272,"sourceCode":"    ///     .finish();\n    /// ```\n    #[cfg(feature = \"cookies\")]\n    pub fn cookie(&mut self, cookie: cookie::Cookie<'_>) -> &mut Self {\n        match cookie.to_string().try_into_value() {\n            Ok(hdr_val) => self.append_header((header::SET_COOKIE, hdr_val)),\n            Err(err) => {\n                self.error = Some(err.into());\n                self\n            }\n        }\n    }\n\n    /// Returns a reference to the response-local data/extensions container.\n    #[inline]\n    pub fn extensions(&self) -> Ref<'_, Extensions> {\n        self.res\n            .as_ref()\n            .expect(\"cannot reuse response builder\")\n            .extensions()\n    }\n\n    /// Returns a mutable reference to the response-local data/extensions container.\n    #[inline]\n    pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {\n        self.res\n            .as_mut()\n            .expect(\"cannot reuse response builder\")\n            .extensions_mut()\n    }\n\n    /// Set a body and build the `HttpResponse`.\n    ///\n    /// Unlike [`message_body`](Self::message_body), errors are converted into error\n    /// responses immediately.\n    ///\n    /// `HttpResponseBuilder` can not be used after this call.","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/actix/actix-web/blob/937960ca67f20e14ffe2a075bf6d4593502be12c/actix-web/src/response/builder.rs#L254-L290","documentation":"`HttpResponseBuilder` holds the in-progress response in `res: Option<...>`. Consuming methods (`body`, `message_body`, `finish`) call `.take()`, leaving `res = None`. `extensions()` at actix-web/src/response/builder.rs:269-273 reads `self.res.as_ref().expect(\"cannot reuse response builder\")`, so calling `extensions()` after the builder was finished panics.","triggerScenarios":"Calling `.finish()` (or `.body(...)`) on a builder, then calling `.extensions()` on the same builder instance.","commonSituations":"Storing a builder in a variable, finishing it, and accidentally touching it again; or shared/multiple-finish code paths.","solutions":["Treat `finish()`/`body()`/`message_body()` as the terminal call — never use the builder afterward.","Read `extensions()`/`extensions_mut()` before finishing the response.","If you need extension data after building, capture it from the returned `HttpResponse` via `res.extensions()` instead of the builder."],"exampleFix":"// before\nlet mut b = HttpResponse::Ok();\nb.insert_header((\"X\", \"1\"));\nlet resp = b.finish();\nlet ext = b.extensions(); // panics\n\n// after\nlet mut b = HttpResponse::Ok();\nb.insert_header((\"X\", \"1\"));\nlet ext = b.extensions();      // read before finish\nlet resp = b.finish();\n// or use resp.extensions() afterwards","handlingStrategy":"validation","validationCode":"// Treat the builder as single-use. If you must track state, wrap usage so that\n// extensions()/extensions_mut() are only called before a terminal method.\n// Pseudocode guard for your own helpers:\nstruct SafeBuilder { b: Option<HttpResponseBuilder> }\nimpl SafeBuilder {\n    fn extensions(&self) -> bool { self.b.is_some() }\n    fn finish(&mut self) -> HttpResponse {\n        self.b.take().unwrap().finish()\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call extensions()/extensions_mut() only before finish/body/message_body.","Read extension data from the returned HttpResponse after building."],"tags":["rust","actix","actix-web","response","runtime","panic","builder"],"analyzedSha":"937960ca67f20e14ffe2a075bf6d4593502be12c","analyzedAt":"2026-08-06T01:15:46.978Z","schemaVersion":2}