redis/node-redis · error · Error
Unknown response policy
Error message
Unknown response policy ${responsePolicy} What it means
Thrown in the cluster command dispatch when a command's resolved response policy is not present in the RESPONSE_REDUCERS registry. Validation happens before any per-node command is dispatched (so no orphaned in-flight requests result). An unknown response policy means the command metadata or custom command specified a reducer the cluster cannot apply to fan-out replies.
Solutions
- For custom commands, use a supported response policy (ONE_SUCCEEDED, ALL_SUCCEEDED, AGG_LOGICAL_AND, AGG_LOGICAL_OR, AGG_MIN, AGG_MAX, AGG_SUM, SPECIAL, DEFAULT_KEYLESS, DEFAULT_KEYED) or omit to default.
- Upgrade node-redis so the response policy table matches the command metadata in use.
- Audit any code setting command metadata .response to confirm it uses a registered value.
- Report with the command name and resolved responsePolicy if it fires on a built-in command.
Example fix
// before (custom command metadata with bad policy)
{ RESPONSE_POLICY: 'sum_all' /* not in registry */ }
// after
{ RESPONSE_POLICY: 'agg_sum' } // valid registry value Defensive patterns
Strategy: validation
Validate before calling
import { RESPONSE_POLICIES_WITH_DEFAULTS } from '@redis/client';
function isValidResponsePolicy(p: string): boolean {
return Object.values(RESPONSE_POLICIES_WITH_DEFAULTS).includes(p as never);
}
isValidResponsePolicy(metadata.response); Type guard
function isKnownResponsePolicy(p: unknown, known: readonly string[]): p is string {
return typeof p === 'string' && known.includes(p);
} Try / catch
try {
await cluster.executeCommand(...);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unknown response policy')) {
// fix command metadata to use a supported policy
} else throw e;
} Prevention
- Use only registered response policies for custom command metadata.
- Keep node-redis version aligned with the command metadata in use.
- Import policy constants from the library rather than hardcoding strings.
When it happens
Trigger: Defining a custom command or script whose metadata sets a response value not in RESPONSE_POLICIES_WITH_DEFAULTS. A version mismatch where the command's response policy was introduced in a newer library version than installed. Invalid metadata injected for a custom multi-shard command.
Common situations: Custom/script commands with manually-configured response policies that are misspelled or unsupported; running a built-in command whose policy was added in a newer release; overriding command metadata with an invalid response value.
Related errors
- Unknown request policy
- Client Side Caching is only supported with RESP3
- Cluster already open
- [Proxy] No node with no connections
- Request policy produced no target nodes
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/695ccd8c022a029c.
Report an issue: GitHub.
Appendix: source
Thrown at packages/client/lib/cluster/index.ts:577
// none of them default-keyed).
if (
requestPolicy === REQUEST_POLICIES_WITH_DEFAULTS.DEFAULT_KEYED &&
responsePolicy === RESPONSE_POLICIES_WITH_DEFAULTS.DEFAULT_KEYED
) {
return this._execute(parser, readonly, options, makeFn(parser));
}
// https://redis.io/docs/latest/develop/reference/command-tips
const router = REQUEST_ROUTERS[requestPolicy];
if (!router) {
throw new Error(`Unknown request policy ${requestPolicy}`);
}
// Validated before any per-node promise is dispatched — throwing after
// would orphan in-flight rejections (unhandled-rejection noise) and run
// side effects for a reply that can never be reduced.
const reducer = RESPONSE_REDUCERS[responsePolicy];
if (!reducer) {
throw new Error(`Unknown response policy ${responsePolicy}`);
}
// Routers are typed against the erased base cluster types (routing is
// below the typed command surface); bridge this instantiation's slots in.
const plan = await router(
this._slots as unknown as Parameters<typeof router>[0],
parser,
readonly,
policy.keySpecs
);
if (plan.length === 0) {
throw new Error(`Request policy ${requestPolicy} produced no target nodes`);
}
// Numeric aggregation must see raw numbers: strip the caller's type
// mapping from the per-node executions (a `NUMBER: String` mapping would
// feed strings into the numeric reducers) and re-apply it to the
// aggregated result below. Pass-through policies keep the mapping — theirView on GitHub (pinned to 90fd0652bc)