Subclass of Error with optional:
code— Machine-readable stringconfig— Merged request config (may contain secrets)response— Present for failedvalidateStatus(ERR_BAD_RESPONSE)request—{ url }when available
| Code | Meaning |
|---|---|
ERR_BAD_RESPONSE |
HTTP status failed validateStatus |
ERR_NETWORK |
Network / unexpected throw from fetch |
ERR_PARSE |
Response body could not be parsed |
ERR_CANCELED |
Aborted (typically external signal or user abort) |
ERR_TIMEOUT |
Per-request timeout elapsed (internal timer aborted fetch before user signal) |
ERR_RETRY_TIMEOUT |
Total retry budget (retry.timeoutTotalMs) exceeded (monotonic clock) |
Type guard: err is OpenFetchError.
isHTTPError(err)—OpenFetchErrorwithcode === "ERR_BAD_RESPONSE"and aresponseattached.isTimeoutError(err)—OpenFetchErrorwithERR_TIMEOUT(per-attempt fetch timeout) orERR_RETRY_TIMEOUT(whole retry sequence budget).
Thrown when jsonSchema or fluent .json(schema) validation fails. Not an OpenFetchError (the HTTP round-trip succeeded; the schema rejected the body). Use isSchemaValidationError for narrowing.
toShape() returns a plain object: message, status, url, method, optional data / headers, code.
config.authis omitted from the shape, but the live error instance may still hold fullconfig— do not send it raw to clients.- For shared or client-facing logs, prefer:
error.toShape({
includeResponseData: false,
includeResponseHeaders: false,
});Default toShape() / toJSON() includes response data and headers (backward compatible).
Optional server-side guard when the URL may be influenced by untrusted input.
- Allows only
http:/https:. - Rejects localhost and literal private / loopback / link-local IPv4 and common IPv6 cases.
- Does not stop DNS rebinding (hostname resolving to internal IPs). Combine with hostname allowlists, egress controls, or proxies as needed.
Throws Error with messages prefixed openfetch: assertSafeHttpUrl:.
When you build your own log lines (outside the debug plugin), use maskHeaderValues from the main package with MaskHeaderStrategy partial or hash — same strategies as debug({ maskStrategy, … }). See Configuration for the export table.
If you hold a native Response (for example from rawResponse or .raw()) and need to read the body twice, use cloneResponse(res) from the package (or res.clone() on the Response).
See Retry & cache: use varyHeaderNames or a custom key for per-user GETs.
- Package
SECURITY.mdandnpm run test:security(security test harness in the repo).