Profiles·Public

undici

semver>=5.0.0postconditions25functions16last verified2026-06-18coverage score100%

Postconditions — what we check

  • request · network-error-handling
    error
    Whennetwork failure, DNS error, timeout, connection refused
    ThrowsPromise rejection with Error
    Required handlingUse try-catch (async/await) or .catch() (promises)
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • fetch · network-error-handling
    error
    Whennetwork failure, DNS error, timeout, connection refused, certificate errors
    ThrowsTypeError with 'fetch failed' message and cause property containing underlying error (UND_ERR_SOCKET, etc.)
    Required handlingUse try-catch (async/await) or .catch() (promises)
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • stream · stream-network-error
    error
    Whennetwork failure, DNS error, timeout (UND_ERR_CONNECT_TIMEOUT, UND_ERR_HEADERS_TIMEOUT, UND_ERR_BODY_TIMEOUT, UND_ERR_SOCKET) before or during streaming
    ThrowsConnectTimeoutError (UND_ERR_CONNECT_TIMEOUT), HeadersTimeoutError (UND_ERR_HEADERS_TIMEOUT), BodyTimeoutError (UND_ERR_BODY_TIMEOUT), SocketError (UND_ERR_SOCKET)
    Required handlingWrap await stream() call in try-catch; check error.code for specific timeout vs socket failure
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][2]
  • stream · stream-factory-invalid-return
    error
    Whenfactory function returns non-Writable value
    ThrowsInvalidReturnValueError (UND_ERR_INVALID_RETURN_VALUE)
    Required handlingWrap await stream() in try-catch; factory must return a stream.Writable
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • connect · connect-network-error
    error
    Whenconnection refused, timeout, or proxy authentication failure
    ThrowsConnectTimeoutError (UND_ERR_CONNECT_TIMEOUT), SocketError (UND_ERR_SOCKET), SecureProxyConnectionError (UND_ERR_PRX_TLS)
    Required handlingWrap await connect() in try-catch; check error.code for UND_ERR_CONNECT_TIMEOUT vs UND_ERR_PRX_TLS
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][2]
  • upgrade · upgrade-network-error
    error
    Whennetwork failure or server rejects upgrade request
    ThrowsConnectTimeoutError (UND_ERR_CONNECT_TIMEOUT), SocketError (UND_ERR_SOCKET), HeadersTimeoutError (UND_ERR_HEADERS_TIMEOUT)
    Required handlingWrap await upgrade() in try-catch
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][2]
  • json · response-json-parse-error
    error
    Whenserver returns non-JSON body (HTML error page, empty body, binary content)
    ThrowsSyntaxError: Unexpected token in JSON
    Required handlingWrap await response.json() in try-catch; always check response.ok before calling .json()
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4][2]
  • json · response-ok-not-checked
    warning
    Whenresponse.json() called without checking response.ok first
    ThrowsSyntaxError when server returns error page instead of JSON
    Required handlingAlways check response.ok or response.status before calling response.json()
    costmediumin prodsilent failureusers seelost datavisibilitysilent
    Sources[5][2]
  • text · response-text-no-try-catch
    error
    Whenresponse.text() called in async context without try-catch wrapping the await. Network failure during body streaming (UND_ERR_SOCKET, UND_ERR_BODY_TIMEOUT) after headers arrive causes the body promise to reject.
    ThrowsBodyTimeoutError (UND_ERR_BODY_TIMEOUT) if body download exceeds bodyTimeout. SocketError (UND_ERR_SOCKET) if TCP connection drops mid-body. RequestAbortedError (UND_ERR_ABORTED) if AbortSignal fires during body read.
    Required handlingWrap await response.text() in try-catch. Network can fail AFTER headers are received — a successful fetch() does not guarantee the body will arrive intact. Critical in streaming scenarios or large response bodies.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][6]
  • text · response-text-body-already-read
    error
    Whenresponse.text() called after the body has already been consumed by a previous call to .text(), .json(), .arrayBuffer(), .blob(), .bytes(), or .body.getReader().
    ThrowsTypeError: 'Body is unusable: Body has already been read' (confirmed from undici/lib/web/fetch/body.js source)
    Required handlingCaller MUST call response.text() only once per Response object. If the same response body needs to be read multiple times, clone the Response before consuming: const cloned = response.clone(); await cloned.text(). Alternatively, store the result in a variable and reuse it.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7][8]
  • arrayBuffer · response-arraybuffer-no-try-catch
    error
    Whenresponse.arrayBuffer() called without try-catch. Body streaming errors (timeout, socket drop) cause the promise to reject.
    ThrowsBodyTimeoutError (UND_ERR_BODY_TIMEOUT), SocketError (UND_ERR_SOCKET), RequestAbortedError (UND_ERR_ABORTED), ResponseExceededMaxSizeError (UND_ERR_RES_EXCEEDED_MAX_SIZE) when Client configured with maxResponseSize.
    Required handlingWrap await response.arrayBuffer() in try-catch. Large binary downloads are especially vulnerable to BodyTimeoutError. If a maxResponseSize limit is configured on the Client, ResponseExceededMaxSizeError will be thrown for files that exceed the limit.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][9]
  • arrayBuffer · response-arraybuffer-body-already-read
    error
    Whenresponse.arrayBuffer() called after the body has already been consumed by a previous call to any body-reading method or .body.getReader().
    ThrowsTypeError: 'Body is unusable: Body has already been read'
    Required handlingUse response.clone() before consuming the body if multiple reads are needed. Store the ArrayBuffer result in a variable rather than calling arrayBuffer() twice.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[10][8]
  • WebSocket · websocket-constructor-syntax-error
    warning
    Whennew WebSocket(url) called with an invalid URL format, non-ws/wss scheme, or duplicate/invalid subprotocol strings in the protocols array.
    ThrowsDOMException with name 'SyntaxError'. Thrown synchronously from the constructor, not from an event or promise. Occurs immediately when new WebSocket() is called.
    Required handlingWrap new WebSocket(url) in try-catch if the URL comes from user input or configuration. Static URLs (hardcoded ws://...) are safe to skip try-catch. Dynamic URLs from config files or env vars should be validated or wrapped.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[11][12]
  • WebSocket · websocket-connection-error-not-handled
    error
    WhenWebSocket connection failure (server unreachable, TLS handshake failure, server rejected upgrade) occurs but no 'onerror' or 'error' event handler is registered. Connection errors are dispatched via the error event, NOT thrown from the constructor.
    ThrowsDoes NOT throw. Instead dispatches an ErrorEvent to the 'error' event listener. If no error listener is registered, the error is silently swallowed in browsers but in Node.js the uncaught error causes process crash (UnhandledErrorEvent). After the error event, the 'close' event fires with code 1006 (abnormal closure).
    Required handlingAlways register ws.onerror or ws.addEventListener('error', handler) before the connection attempt. A missing error handler means connection failures are invisible. Example: const ws = new WebSocket('wss://api.example.com/ws'); ws.onerror = (event) => { logger.error('WebSocket connection failed', event); }; ws.onclose = (event) => { if (!event.wasClean) reconnect(); };
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
  • close · dispatcher-close-already-destroyed
    warning
    Whenclient.close() / pool.close() called AFTER client.destroy() has already been called. The close() promise will reject with ClientDestroyedError.
    ThrowsClientDestroyedError (UND_ERR_DESTROYED): 'The client is destroyed' Confirmed from undici/lib/dispatcher/dispatcher-base.js source.
    Required handlingTrack dispatcher lifecycle state. In graceful shutdown handlers, do not call close() if destroy() may have been called on error paths. Use the destroyed property to check: if (!client.destroyed) await client.close(). In finally blocks that attempt cleanup: wrap close() in try-catch.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[15][16]
  • blob · response-blob-no-try-catch
    error
    Whenresponse.blob() called without try-catch. Body streaming errors (timeout, socket drop, exceeded max response size) cause the promise to reject.
    ThrowsBodyTimeoutError (UND_ERR_BODY_TIMEOUT) if body download exceeds bodyTimeout. SocketError (UND_ERR_SOCKET) if TCP connection drops mid-body. RequestAbortedError (UND_ERR_ABORTED) if AbortSignal fires during body read. ResponseExceededMaxSizeError (UND_ERR_RES_EXCEEDED_MAX_SIZE) when Client is configured with maxResponseSize limit.
    Required handlingWrap await response.blob() in try-catch. Like arrayBuffer(), blob() buffers the entire body in memory, so large downloads can hit ResponseExceededMaxSizeError when maxResponseSize is configured on the Client. Binary downloads have a higher rate of bodyTimeout failures than text responses.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[17][8][3]
  • blob · response-blob-body-already-read
    error
    Whenresponse.blob() called after the body has already been consumed by any prior call to .text(), .json(), .arrayBuffer(), .bytes(), .formData(), .blob(), or .body.getReader().
    ThrowsTypeError: 'Body is unusable: Body has already been read' (confirmed from undici/lib/web/fetch/body.js line 467)
    Required handlingUse response.clone() before consuming the body if multiple reads are needed. Store the Blob result in a variable rather than calling blob() twice.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[17][8]
  • bytes · response-bytes-no-try-catch
    error
    Whenresponse.bytes() called without try-catch. Body-streaming errors (timeout, socket drop, exceeded max response size) cause the promise to reject.
    ThrowsBodyTimeoutError (UND_ERR_BODY_TIMEOUT), SocketError (UND_ERR_SOCKET), RequestAbortedError (UND_ERR_ABORTED), ResponseExceededMaxSizeError (UND_ERR_RES_EXCEEDED_MAX_SIZE).
    Required handlingWrap await response.bytes() in try-catch. Behavior matches arrayBuffer() — large binary payloads can hit bodyTimeout (default 300s) or ResponseExceededMaxSizeError when a Client is configured with maxResponseSize. Unhandled rejections crash the Node.js process under default settings.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[18][8]
  • bytes · response-bytes-body-already-read
    error
    Whenresponse.bytes() called after the body has already been consumed by a previous call to any body-reading method or .body.getReader().
    ThrowsTypeError: 'Body is unusable: Body has already been read'
    Required handlingUse response.clone() before consuming the body if multiple reads are needed. Store the Uint8Array result in a variable rather than calling bytes() twice.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[18][8]
  • formData · response-formdata-no-try-catch
    error
    Whenresponse.formData() called without try-catch. Body-streaming errors AND multipart parsing errors AND unsupported Content-Type all cause rejection.
    ThrowsBodyTimeoutError (UND_ERR_BODY_TIMEOUT), SocketError (UND_ERR_SOCKET), RequestAbortedError (UND_ERR_ABORTED). TypeError 'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded"' if the server returned a body with a non-form Content-Type (e.g. application/json error responses). TypeError from multipart parser if multipart boundaries are malformed.
    Required handlingWrap await response.formData() in try-catch. formData() has the highest probability of throwing among body-consumer methods because it can fail for THREE distinct reasons: network errors, multipart-parse errors, and unsupported Content-Type. Always check response.ok first — error responses rarely return form-encoded bodies, so .formData() on an HTTP 500 with a JSON error body will throw the Content-Type TypeError.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[19][8]
  • formData · response-formdata-unsupported-content-type
    warning
    Whenresponse.formData() called on a response whose Content-Type is not multipart/form-data or application/x-www-form-urlencoded (e.g. an HTTP 500 response with application/json or text/html body).
    ThrowsTypeError: 'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".' Confirmed from undici/lib/web/fetch/body.js line 380-384.
    Required handlingCheck response.headers.get('content-type') before calling .formData(), OR always wrap the await in try-catch and treat the TypeError as a parsing failure (not a network failure). Webhook proxies should validate Content-Type explicitly to distinguish bad-payload from network-error.
    costlowin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[8][19]
  • pipeline · pipeline-missing-error-listener
    error
    Whenundici.pipeline() return value used without registering an 'error' event listener on the returned Duplex. Network failures (UND_ERR_SOCKET, UND_ERR_CONNECT_TIMEOUT, UND_ERR_BODY_TIMEOUT) are dispatched as 'error' events on the Duplex — they do NOT throw synchronously and do NOT reject a Promise.
    ThrowsDoes NOT throw synchronously. Error is emitted as 'error' event on the returned Duplex stream. If no 'error' listener is registered, Node.js treats it as an uncaught exception and crashes the process under default configuration.
    Required handlingAlways register an 'error' listener on the Duplex returned by pipeline(), OR pass the Duplex to stream.pipeline() / pipeline.promisify() which handles the error path. Direct usage: const duplex = undici.pipeline(url, opts, handler); duplex.on('error', (err) => { logger.error(err); }); Or via stream/promises: await pipeline(source, undici.pipeline(url, opts, handler), dest);
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[20][21]
  • destroy · dispatcher-destroy-no-try-catch
    error
    Whendispatcher.destroy() called in async context without try-catch wrapping the await. Pending request callbacks reject with the destroy error, and the destroy() promise itself may reject if invalid arguments are passed.
    ThrowsInvalidArgumentError (UND_ERR_INVALID_ARG) if a non-function callback is passed synchronously. The returned Promise resolves successfully in normal shutdown, but rejection-handling is required when destroy() is called inside finally blocks where errors may already be in flight.
    Required handlingIn emergency shutdown paths (process SIGTERM, error recovery), wrap await dispatcher.destroy() in try-catch. Destroying a Pool/Agent during active request handling can cause request callbacks to fire with the destroy error — those handlers must also be try-catched. Pattern: try { await client.destroy(new Error('shutdown')); } catch (e) { logger.warn('destroy failed', e); }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[15][22]
  • EventSource · eventsource-constructor-syntax-error
    warning
    Whennew EventSource(url) called with an invalid URL format that fails URL parsing per the WHATWG URL spec.
    ThrowsDOMException with name 'SyntaxError'. Thrown synchronously from the constructor. Confirmed from undici/lib/web/eventsource/eventsource.js line 143-144.
    Required handlingWrap new EventSource(url) in try-catch if the URL comes from user input, query strings, env vars, or configuration. Hardcoded URLs are safe to skip the try-catch. Dynamic URLs (e.g. SSE endpoint built from request params) must be validated or wrapped.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[23][24]
  • EventSource · eventsource-connection-error-not-handled
    error
    WhenEventSource connection failure (server unreachable, TLS handshake failure, non-2xx response, malformed SSE stream) occurs but no 'onerror' or 'error' event listener is registered. Connection errors are dispatched via the error event, NOT thrown from the constructor.
    ThrowsDoes NOT throw. Instead dispatches an Event of type 'error' to the 'error' listener. If no error listener is registered, Node.js treats the EventTarget error event as silent — but EventSource then enters CONNECTING state and retries indefinitely, with no observability of the failure.
    Required handlingAlways register es.onerror or es.addEventListener('error', handler) before the connection attempt. Without it, SSE connection failures are invisible AND EventSource silently retries forever — a hung SSE consumer that never receives data with no log signal. Example: const es = new EventSource('https://api.example.com/events'); es.onerror = (event) => { logger.error('SSE connection failed, readyState=' + es.readyState); if (es.readyState === EventSource.CLOSED) es.close(); };
    costmediumin prodsilent failureusers seelost datavisibilitysilent

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]npmjs.com/package/undicihttps://www.npmjs.com/package/undici
  2. [2]undici.nodejs.orghttps://undici.nodejs.org/
  3. [3]github.com/nodejs/undicihttps://github.com/nodejs/undici/blob/main/docs/docs/api/Errors.md
  4. [4]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/json
  5. [5]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/ok
  6. [6]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/text#exceptions
  7. [7]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/text
  8. [8]github.com/nodejs/undicihttps://github.com/nodejs/undici/blob/main/lib/web/fetch/body.js
  9. [9]github.com/nodejs/undicihttps://github.com/nodejs/undici/blob/main/lib/dispatcher/client-h1.js
  10. [10]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/arrayBuffer
  11. [11]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket#exceptions
  12. [12]github.com/nodejs/undicihttps://github.com/nodejs/undici/blob/main/lib/web/websocket/websocket.js
  13. [13]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/WebSocket#events
  14. [14]rfc-editor.org/rfc/rfc6455https://www.rfc-editor.org/rfc/rfc6455
  15. [15]github.com/nodejs/undicihttps://github.com/nodejs/undici/blob/main/lib/dispatcher/dispatcher-base.js
  16. [16]undici.nodejs.orghttps://undici.nodejs.org/#/docs/api/Dispatcher
  17. [17]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/blob
  18. [18]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/bytes
  19. [19]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/Response/formData
  20. [20]github.com/nodejs/undicihttps://github.com/nodejs/undici/blob/main/lib/api/api-pipeline.js
  21. [21]undici.nodejs.orghttps://undici.nodejs.org/#/docs/api/Dispatcher.md?id=dispatcherpipelineoptions-handler
  22. [22]undici.nodejs.orghttps://undici.nodejs.org/#/docs/api/Dispatcher.md?id=dispatcherdestroyerror-callback
  23. [23]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource
  24. [24]github.com/nodejs/undicihttps://github.com/nodejs/undici/blob/main/lib/web/eventsource/eventsource.js
  25. [25]developer.mozilla.org/en-US/docshttps://developer.mozilla.org/en-US/docs/Web/API/EventSource#events
  26. [26]html.spec.whatwg.org/multipage/server-sent-events.htmlhttps://html.spec.whatwg.org/multipage/server-sent-events.html
Need a different package?
Request a profile