{"record":{"id":"f32d445f9a15e0d0","repo":"denoland/deno","slug":"err-http-socket-assigned","errorCode":"ERR_HTTP_SOCKET_ASSIGNED","errorMessage":"ServerResponse has an already assigned socket","messagePattern":"ServerResponse has an already assigned socket","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_http_server.js","lineNumber":384,"sourceCode":"      response: this,\n    });\n  }\n}\nObjectSetPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype);\nObjectSetPrototypeOf(ServerResponse, OutgoingMessage);\n\nServerResponse.prototype.statusCode = 200;\nServerResponse.prototype.statusMessage = undefined;\n\nfunction onServerResponseClose() {\n  if (this._httpMessage) {\n    emitCloseNT(this._httpMessage);\n  }\n}\n\nServerResponse.prototype.assignSocket = function assignSocket(socket) {\n  if (socket._httpMessage) {\n    throw new ERR_HTTP_SOCKET_ASSIGNED();\n  }\n  socket._httpMessage = this;\n  if (socket._parent) {\n    socket._parent._httpMessage = this;\n    socket._parent._httpMessageDetached = false;\n  }\n  socket.on(\"close\", onServerResponseClose);\n  this.socket = socket;\n  this.emit(\"socket\", socket);\n  this._flush();\n};\n\nServerResponse.prototype.detachSocket = function detachSocket(socket) {\n  assert(socket._httpMessage === this);\n  socket.removeListener(\"close\", onServerResponseClose);\n  socket._httpMessage = null;\n  socket._httpMessageDetached = true;\n  if (socket._parent) {","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/_http_server.js#L366-L402","documentation":"ERR_HTTP_SOCKET_ASSIGNED from ServerResponse.assignSocket(): a socket may be bound to at most one active ServerResponse, tracked as socket._httpMessage. Calling res.assignSocket(sock) when sock._httpMessage is already set — the socket still serves another response — throws, preventing two responses from interleaving writes on one connection.","triggerScenarios":"Calling res.assignSocket(sock) twice for the same pair; binding a response to a socket grabbed from a live server 'connection' event that another response owns; manually driving ServerResponse the way http.Server does internally.","commonSituations":"Custom HTTP frameworks or test harnesses that construct and bind ServerResponse by hand; interposition layers on connection events; socket-management code ported between Node/Deno versions where lifecycle details differ.","solutions":["Let http.Server bind responses to sockets automatically instead of calling assignSocket manually","Call res.detachSocket(sock) on the previous owner before assigning a new response","Guard the assignment: check sock._httpMessage === undefined before res.assignSocket(sock)"],"exampleFix":"// before\nres2.assignSocket(sock); // sock._httpMessage still set by res1 -> throws\n\n// after\nres1.detachSocket(sock);\nres2.assignSocket(sock);","handlingStrategy":"type-guard","validationCode":"if (sock._httpMessage !== undefined) {\n  sock._httpMessage.detachSocket(sock); // release the previous owner first\n}\nres.assignSocket(sock);","typeGuard":"const isSocketFree = (sock) => sock._httpMessage === undefined;","tryCatchPattern":"try {\n  res.assignSocket(sock);\n} catch (e) {\n  if (e.code === 'ERR_HTTP_SOCKET_ASSIGNED') {\n    // socket already bound; detach previous owner or pick another socket\n    sock._httpMessage?.detachSocket(sock);\n    res.assignSocket(sock);\n  } else throw e;\n}","preventionTips":["Treat socket._httpMessage as internal state; prefer the server's own response lifecycle","Pair every assignSocket with an eventual detachSocket","In tests, create a fresh socket per response instead of reusing one"],"tags":["http","socket","server","node-compat"],"backgroundTag":"http-socket-already-assigned","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}