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

  1. 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.
  2. Upgrade node-redis so the response policy table matches the command metadata in use.
  3. Audit any code setting command metadata .response to confirm it uses a registered value.
  4. 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

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


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 — their

View on GitHub (pinned to 90fd0652bc)