superagent
>=3.7.0postconditions14functions9last verified2026-06-24coverage score100%Postconditions: what we check
- get · network-error-handlingerrorWhennetwork failure, DNS error, timeout, connection refused, HTTP 4xx/5xx errorsThrows
Error with status, response, timeout fields (Promise rejection)Required handlingUse try-catch (async/await) or .catch() (promises) or .end() callbackcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - get · timeout-error-identifiablewarningWhenrequest exceeds deadline (.timeout(ms)) or response timeout (.timeout({response:ms}))Throws
Error with err.timeout=<number> and err.code='ETIME' (deadline) or 'ETIMEDOUT' (response timeout)Required handlingCheck err.timeout in catch block to distinguish timeout from network errors; retry with backoff if appropriatecostlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - get · max-response-size-exceedederrorWhenresponse body exceeds maxResponseSize limit (default 200MB for buffered responses)Throws
Error with code='ETOOLARGE' and message='Maximum response size reached'Required handlingHandle in catch block; check err.code === 'ETOOLARGE' for specific handling; use streaming .pipe() for large responses instead of bufferingcostmediumin prodimmediate exceptionusers seelost datavisibilitysilentSources[3] - post · network-error-handlingerrorWhennetwork failure, DNS error, timeout, connection refused, HTTP 4xx/5xx errorsThrows
Error with status, response, timeout fields (Promise rejection)Required handlingUse try-catch (async/await) or .catch() (promises) or .end() callbackcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - post · timeout-error-identifiablewarningWhenrequest exceeds deadline or response timeoutThrows
Error with err.timeout=<number> and err.code='ETIME' (deadline) or 'ETIMEDOUT' (response timeout)Required handlingCheck err.timeout in catch to distinguish timeout from auth/rate-limit errors; POST requests are not idempotent so do not auto-retry without deduplicationcostlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - put · network-error-handlingerrorWhennetwork failure, DNS error, timeout, connection refused, HTTP 4xx/5xx errorsThrows
Error with status, response, timeout fields (Promise rejection)Required handlingUse try-catch (async/await) or .catch() (promises) or .end() callbackcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - patch · network-error-handlingerrorWhennetwork failure, DNS error, timeout, connection refused, HTTP 4xx/5xx errorsThrows
Error with status, response, timeout fields (Promise rejection)Required handlingUse try-catch (async/await) or .catch() (promises) or .end() callbackcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - delete · network-error-handlingerrorWhennetwork failure, DNS error, timeout, connection refused, HTTP 4xx/5xx errorsThrows
Error with status, response, timeout fields (Promise rejection)Required handlingUse try-catch (async/await) or .catch() (promises) or .end() callbackcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - del · network-error-handlingerrorWhennetwork failure, DNS error, timeout, connection refused, HTTP 4xx/5xx errorsThrows
Error with status, response, timeout fields (Promise rejection)Required handlingUse try-catch (async/await) or .catch() (promises) or .end() callbackcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - head · network-error-handlingerrorWhennetwork failure, DNS error, timeout, connection refused, HTTP 4xx/5xx errorsThrows
Error with status, response, timeout fields (Promise rejection)Required handlingUse try-catch (async/await) or .catch() (promises) or .end() callbackcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - pipe · pipe-errors-not-promise-rejectionserrorWhenAny error during a piped request: network failure, DNS resolution error, connection refused, HTTP 4xx/5xx response, or timeout. Unlike awaited superagent calls, piped requests bypass the Promise chain entirely — .pipe() returns the destination stream immediately, not a Promise.Throws
Does NOT throw or reject a Promise. Errors are emitted as 'error' events: (1) Network/HTTP errors: emitted on the Request object via req.emit('error', err) where err.status is set for HTTP errors, absent for network/DNS errors. (2) Decompression errors (gzip/deflate responses): emitted on the destination stream via stream.emit('error', err). err.code='Z_BUF_ERROR' (truncated gzip) is silently swallowed by superagent; other zlib errors propagate to dest stream. If no 'error' listener is registered, Node.js throws an uncaught exception and may crash the process.Required handlingMUST register an 'error' event listener on the Request object before calling pipe(). Try-catch and async/await provide zero protection — errors bypass them silently, leaving the destination stream in an incomplete state with no indication of failure. Correct pattern: const req = superagent.get(url); req.on('error', handler); req.pipe(dest); Also register 'error' on the destination stream for decompression errors: dest.on('error', (err) => { /* handle decompression errors */ });costhighin prodsilent failureusers seelost datavisibilitysilent - pipe · pipe-cannot-be-mixed-with-promiseerrorWhenCalling .pipe() after .then()/.catch()/await on the same request, or attempting to pipe the Response object (res.pipe()) received in an .end() callback. Common mistake: const res = await superagent.get(url); res.pipe(stream) — pipe() belongs on the Request, not the Response, and await has already consumed the response via end().Throws
Synchronous Error with message "end() has already been called, so it's too late to start piping" when pipe() is called on the Response object after end() has run. If pipe() is called on the Request after await (same request), behavior is undefined and data may be silently lost without any error.Required handlingUse EITHER streaming OR promise/callback — never both on the same request. Streaming: const req = superagent.get(url); req.on('error', h); req.pipe(stream); Promise: const res = await superagent.get(url); process(res.body); If a response must be both processed and streamed, buffer first then write manually.costmediumin prodimmediate exceptionusers seelost datavisibilityvisibleSources[4] - agent · agent-request-network-errorerrorWhennetwork failure, DNS error, connection refused, or HTTP 4xx/5xx on agent.get/post/put/patch/delete/head()Throws
Error with err.status (HTTP errors) or no err.status (network errors), plus err.response for HTTP errorsRequired handlingWrap agent HTTP method calls in try-catch; agent persists cookies so session errors (401, 403) may indicate expired auth that must be re-establishedcostmediumin prodimmediate exceptionusers seeservice unavailablevisibilitysilentSources[6] - agent · agent-session-auth-failureerrorWhen401 Unauthorized or 403 Forbidden response when agent session/cookie has expiredThrows
Error with err.status=401 or err.status=403 and err.response containing the response bodyRequired handlingCatch 401/403 specifically and re-authenticate: check err.status === 401 to detect session expiry. Agents carry cookies across requests — a 401 mid-session means the cookie/token expired and must be refreshed before retrying. Do not silently swallow these errors or the agent will continue sending expired credentials.costmediumin prodimmediate exceptionusers seeauthentication failurevisibilitysilent
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
- [1]forwardemail.github.io/superagentSuperagent
- [2]forwardemail.github.io/superagentSuperagent
- [3]forwardemail.github.io/superagentSuperagent
- [4]forwardemail.github.io/superagentSuperagent
- [5]forwardemail.github.io/superagentSuperagent
- [6]forwardemail.github.io/superagentSuperagent
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources for SuperAgent Contract
Official Documentation
-
SuperAgent Official Website
- URL: https://forwardemail.github.io/superagent/
- Used for: API reference, error handling patterns, HTTP methods
-
SuperAgent GitHub Repository
- URL: https://github.com/forwardemail/superagent
- Used for: Source code verification, issue tracking
-
SuperAgent NPM Package
- URL: https://www.npmjs.com/package/superagent
- Used for: Version information, installation details
Security Analysis
-
Snyk Vulnerability Database
- URL: https://snyk.io/node-js/superagent
- Used for: CVE analysis, security vulnerabilities
- Key finding: v3.7.0+ has all known vulnerabilities fixed
-
Snyk Package Security
- URL: https://security.snyk.io/package/npm/superagent
- Used for: Detailed vulnerability information
Code Examples
-
DefinitelyTyped TypeScript Tests
- URL: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/superagent/superagent-tests.ts
- Used for: Real-world usage patterns, TypeScript examples
-
Snyk Code Examples
- URL: https://snyk.io/advisor/npm-package/superagent/functions/superagent.get
- URL: https://snyk.io/advisor/npm-package/superagent/functions/superagent.post
- Used for: Common usage patterns
Key Behavioral Characteristics
Error Handling
SuperAgent treats 4xx and 5xx responses as errors by default, which is different from fetch() but similar to axios.
Quote from docs:
"SuperAgent treats 4xx and 5xx responses (as well as unhandled 3xx responses) as errors by default. Network failures produce errors with no status or response fields."
Error Object Structure
Errors contain:
err.status- HTTP status code (if applicable)err.response- Full response object (if applicable)err.timeout- Present if timeout occurrederr.message- Error message
HTTP Methods
All standard HTTP verbs are supported:
- GET:
request.get(url) - POST:
request.post(url) - PUT:
request.put(url) - PATCH:
request.patch(url) - DELETE:
request.delete(url)orrequest.del(url)(IE compatibility) - HEAD:
request.head(url)
Execution Patterns
Requests are executed via:
.then()- Promise-basedawait- Async/await.end(callback)- Legacy callback
Quote from docs:
"A request can be initiated by invoking the appropriate method on the request object, then calling .then() (or .end() or await) to send the request."
Version Support
Target: v3.7.0+
Rationale:
- All known CVEs fixed in v3.7.0 (Zip Bomb DoS)
- Earlier versions had multiple security vulnerabilities
- Stable API across v3.x - v10.x
Supported range:
^3.7.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
Severity Justification
All HTTP methods: ERROR severity
Rationale:
- Network failures are common in production (DNS, connection timeouts, server downtime)
- HTTP 4xx/5xx errors occur regularly (404, 500, 401, 429 rate limiting)
- SuperAgent treats HTTP errors as promise rejections by default
- Unhandled promise rejections can crash Node.js applications
- Consistent with axios, got, and node-fetch contracts
Date
Contract created: 2026-02-26