@upstash/redis
semver
>=1.0.0postconditions35functions32last verified2026-06-23Postconditions: what we check
- get · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (for API errors) or Error (for network exhaustion)Required handlingCaller MUST wrap in try-catch. Uncaught UpstashError or network errors will propagate and crash the caller. Common API errors include: invalid auth token, quota exceeded, wrong key type. Network errors occur when Upstash is unreachable after the default 5 retry attempts.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - set · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (for API errors) or Error (for network exhaustion)Required handlingCaller MUST wrap in try-catch. UpstashError is thrown for API-level errors (e.g., wrong type for key) and network errors when Upstash is unreachable.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - del · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch. Even deletion can fail if the network is down or the auth token is invalid.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - mget · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch. Batch reads still fail atomically if the HTTP request fails.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - hget · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (including WRONGTYPE if key is not a hash) or ErrorRequired handlingCaller MUST wrap in try-catch. UpstashError is thrown for wrong key type (e.g., key exists but is a string, not a hash) as well as network errors.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - hset · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (including WRONGTYPE if key is not a hash) or ErrorRequired handlingCaller MUST wrap in try-catch. UpstashError for wrong type or auth errors; network error for connectivity failures.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - hgetall · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch. UpstashError includes WRONGTYPE errors; network errors when Upstash is unreachable.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - lpush · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (including WRONGTYPE if key is not a list) or ErrorRequired handlingCaller MUST wrap in try-catch. WRONGTYPE error if key holds a different type.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - lrange · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - sadd · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (including WRONGTYPE if key is not a set) or ErrorRequired handlingCaller MUST wrap in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - smembers · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - zadd · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (including WRONGTYPE if key is not a sorted set) or ErrorRequired handlingCaller MUST wrap in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - zrange · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - expire · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - exists · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - incr · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error responseThrows
UpstashError (including WRONGTYPE if value is not an integer) or ErrorRequired handlingCaller MUST wrap in try-catch. UpstashError if key holds a non-integer value.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - exec · network-or-api-errorerrorWhennetwork failure after retries OR any pipeline command returns an errorThrows
UpstashError or Error — individual command errors throw UpstashError with message 'Command failed: <error>'Required handlingThe pipeline.exec() call MUST be wrapped in try-catch. The entire pipeline fails if the HTTP request fails or any batched command returns an error.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - exec · pipeline-keep-errors-silent-failureerrorWhenpipeline built with pipeline({ keepErrors: true }) executes and individual commands failThrows
does NOT throw — returns array of {error, result} objects; errors are silent if caller does not inspect each elementRequired handlingIf using pipeline({ keepErrors: true }), the returned array MUST be iterated and each element.error checked. Do NOT assume that a resolved promise means all commands succeeded. Pattern: results.forEach((r, i) => { if (r.error) handleError(r.error, commands[i]); });costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - subscribe · subscriber-error-not-thrownerrorWhensubscription fails or a message cannot be received (network error, auth failure, parse failure)Throws
does NOT throw to the calling context — errors are dispatched via Subscriber.on('error', handler) eventRequired handlingCallers MUST attach an error listener: subscriber.on('error', (err) => { ... }) before the subscription begins processing messages. This is not optional. Without it, network interruptions and auth failures are silently swallowed (or crash the process). Additionally attach a 'message' listener to receive data. subscribe() itself need not be awaited for error handling — the returned Subscriber object is the error surface.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - publish · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error (e.g., auth failure, quota exceeded)Throws
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch. Log and alert on UpstashError — a publish failure means the message was not delivered to any subscriber.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - setex · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an errorThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch. On UpstashError, the set did not occur — do not assume the value was stored.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - json.get · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error (invalid path syntax, wrong key type, auth failure)Throws
UpstashError or Error — includes WRONGTYPE if key holds a non-JSON valueRequired handlingCaller MUST wrap in try-catch. Distinguish null return (key/path missing, handle gracefully) from thrown UpstashError (type mismatch, path error, network failure — handle as an error condition).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - json.set · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error (invalid path, non-JSON value, auth failure)Throws
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch. On UpstashError, the write did not complete.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - rpush · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an error (WRONGTYPE if key is not a list)Throws
UpstashError (including WRONGTYPE) or ErrorRequired handlingCaller MUST wrap in try-catch. WRONGTYPE indicates a data model bug (key reuse with different type) that should alert loudly. Network errors should trigger retry logic.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - eval · script-error-or-network-failureerrorWhenLua script contains a runtime error OR network failure after retries OR auth failureThrows
UpstashError — Lua errors are wrapped and re-thrown as UpstashError with the Lua error messageRequired handlingCaller MUST wrap in try-catch. Log UpstashError with the script context — Lua errors are often silent in development and only surface under specific data conditions.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - evalsha · noscript-errorerrorWhenSHA1 hash does not match any script loaded on the server (server restarted, wrong SHA)Throws
UpstashError with NOSCRIPT error code — 'NOSCRIPT No matching script. Please use EVAL.'Required handlingCaller MUST catch UpstashError and check for NOSCRIPT in the message, then retry using eval() with the full Lua script source. Pattern: try { await redis.evalsha(sha, ...) } catch (e) { if (e instanceof UpstashError && e.message.includes('NOSCRIPT')) await redis.eval(script, ...); else throw e; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - evalsha · script-error-or-network-failureerrorWhenLua script contains a runtime error OR network failure after retriesThrows
UpstashErrorRequired handlingCaller MUST wrap in try-catch for all error types beyond NOSCRIPT.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - incrbyfloat · wrongtype-or-not-floaterrorWhenkey holds a non-numeric value OR key holds a value that cannot be represented as a floatThrows
UpstashError — Redis ERR value is not a valid floatRequired handlingCaller MUST wrap in try-catch. Validate that keys used with incrbyfloat are initialized to numeric strings. UpstashError indicates the key holds an incompatible value type.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - getdel · network-or-api-errorerrorWhennetwork failure after retries OR Upstash API returns an errorThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch. On UpstashError, the state of the key is unknown — implement a compensating read (GET) or require re-issuance of the token rather than assuming it was or was not consumed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - xadd · wrongtype-or-network-errorerrorWhenKey exists but holds a non-stream type (WRONGTYPE error) OR network failure after retries OR auth failure OR MAXLEN/MINID approximate-trim eviction edgeThrows
UpstashError (including WRONGTYPE) or ErrorRequired handlingCaller MUST wrap in try-catch. WRONGTYPE is a data-model bug — a non-stream key was reused as a stream — and should alert loudly because subsequent reads will also fail. Network errors during stream append in event-sourcing pipelines can cause lost events: callers MUST decide between (a) at-least-once with idempotent consumers, or (b) catching and queueing the entry locally before retry. Discarding the returned entry ID also discards the only handle that lets a consumer dedupe (use the returned ID, not a client-side ULID, for downstream correlation).costmediumin prodimmediate exceptionusers seelost datavisibilityvisible - xgroup · busygroup-or-nogroup-errorerrorWhenCREATE called on an existing group (BUSYGROUP) OR DESTROY/SETID called on a non-existent group (NOGROUP) OR the target stream key does not exist and MKSTREAM was not supplied for CREATEThrows
UpstashError — error messages include BUSYGROUP, NOGROUP, or 'ERR The XGROUP subcommand requires the key to exist.'Required handlingCaller MUST wrap in try-catch. BUSYGROUP on CREATE is benign during idempotent startup — match on `e.message.includes('BUSYGROUP')` and continue. NOGROUP on DESTROY/SETID indicates a configuration mismatch and should NOT be swallowed silently — log loudly so consumer rebalancing can detect missing groups. Pattern for idempotent consumer-group initialization: try { await redis.xgroup({ type: 'CREATE', key, group, id: '$', mkstream: true }); } catch (e) { if (e instanceof UpstashError && e.message.includes('BUSYGROUP')) { /* ok */ } else throw e; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - xreadgroup · nogroup-errorerrorWhenThe named consumer group does not exist on the target stream (NOGROUP) OR the stream key does not exist OR network failure after retriesThrows
UpstashError — 'NOGROUP No such key ... or consumer group ...'Required handlingCaller MUST wrap in try-catch. NOGROUP commonly fires on cold-start before xgroup CREATE has run — handle it by creating the group (with MKSTREAM) and retrying once. Swallowing NOGROUP without re-creation silently halts every consumer in the group and the queue depth on the stream grows without bound (no visible error in metrics until a depth alert fires hours later).costhighin prodsilent failureusers seelost datavisibilitysilent - copy · copy-result-not-checkedwarningWhenredis.copy(...) called without checking the returned "COPIED" | "NOT_COPIED" string unionThrows
Does not throw on NOT_COPIED — silently returns the string literal. The caller assumes the copy succeeded when in fact the destination key was left untouched.Required handlingCaller MUST capture and branch on the return value. Pattern: const status = await redis.copy(src, dst); if (status === 'NOT_COPIED') { /* handle destination conflict */ } OR pass `{ replace: true }` if overwrite is the intent. Treating copy() as fire-and-forget produces stale/wrong reads from the destination key with no error signal.costlowin prodsilent failureusers seelost datavisibilitysilent - copy · wrongtype-or-network-errorerrorWhenSource key holds a type incompatible with the destination (rare) OR network failure after retries OR auth failureThrows
UpstashError or ErrorRequired handlingCaller MUST wrap in try-catch in addition to checking the return value. Network failures during copy leave the destination in an indeterminate state — implement a verifying read (GET on destination) before assuming success.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - flushdb · destructive-no-try-catcherrorWhenredis.flushdb() called without try-catch in production code pathsThrows
UpstashError on auth failure (NOAUTH) or permission denied (NOPERM in Redis ACL setups) or network failure after retries. Importantly, flushdb DOES succeed on the first call when permissions are granted — silently wiping every key.Required handlingCaller MUST wrap in try-catch AND wrap the call site in an explicit environment guard. Pattern: if (process.env.NODE_ENV !== 'test') throw new Error('flushdb in non-test env'); try { await redis.flushdb(); } catch (e) { log.error('flushdb failed', e); throw e; } A bare flushdb() with no try-catch is treated by reviewers as a destructive op with no logging, no audit trail, and no failure path — exactly the pattern that turns a config typo into a P0 outage. ACL-based auth errors (NOPERM) are silent when swallowed and mask permission-revocation rollouts.costhighin prodimmediate exceptionusers seelost datavisibilityvisible
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
Official documentation
- [2]redis.io/commands/xaddXadd
- [3]upstash.com/docs/redis/sdksXadd
- [4]redis.io/commands/xgroupXgroup
- [5]upstash.com/docs/redis/sdksXgroup
- [6]redis.io/commands/xreadgroupXreadgroup
- [7]upstash.com/docs/redis/sdksXreadgroup
- [8]redis.io/commands/copyCopy
- [9]upstash.com/docs/redis/sdksCopy
- [10]redis.io/commands/flushdbFlushdb
- [11]upstash.com/docs/redis/sdksFlushdb
Source code
- [1]github.com/upstash/upstash-redisupstash/upstash-redis
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources — @upstash/redis
Primary Documentation
- SDK Overview: https://upstash.com/docs/redis/sdks/ts/overview
- Troubleshooting: https://upstash.com/docs/redis/sdks/ts/troubleshooting
- GitHub Repository: https://github.com/upstash/upstash-redis
- npm Package: https://www.npmjs.com/package/@upstash/redis
Error Behavior Evidence
The error types (UpstashError, UpstashJSONParseError, UrlError) and when they are thrown are documented in the source code at:
pkg/error.tsin the GitHub repositorypkg/http.ts— whereUpstashErroris thrown for non-2xx HTTP responses
Key code paths (verified in installed package nodejs.js):
-
Non-2xx response (line ~225 in nodejs.js):
throw new UpstashError(`${body.error}, command was: ${JSON.stringify(req.body)}`); -
Network exhaustion (line ~244 in nodejs.js):
throw error ?? new Error("Exhausted all retries"); -
Pipeline command error (line ~434 in nodejs.js):
throw new UpstashError(`Command failed: ${commandResult.error}`);
Real-World Usage References
- dub (https://github.com/dubinc/dub) — uses @upstash/redis extensively for link caching, click tracking, rate limiting. See
apps/web/lib/upstash/redis.ts. - cal.com (https://github.com/calcom/cal.com) — uses @upstash/redis via
RedisServicewrapper for caching. Seepackages/features/redis/RedisService.ts.
Upstash Error Messages (from docs)
From https://upstash.com/docs/llms.txt:
"WRONGPASS invalid or missing auth token"— authentication failure"ERR max daily request limit exceeded"— quota exhaustion"ERR max concurrent connections exceeded"— connection limit"NOAUTH Authentication Required"— missing auth token- Standard Redis error codes for type mismatches (
WRONGTYPE)
Need a different package?
Request a profile