{"id":"8beeeec685ad2b71","repo":"redis/node-redis","slug":"unknown-request-policy-requestpolicy","errorCode":null,"errorMessage":"Unknown request policy ${requestPolicy}","messagePattern":"Unknown request policy (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/client/lib/cluster/index.ts","lineNumber":570,"sourceCode":"    const responsePolicy = policy.response;\n\n    // Fast path: default-keyed request + response — the overwhelming majority\n    // of traffic (every single-key command). Route by firstKey and pass the\n    // sole reply through, skipping the plan/reducer/post-reply machinery,\n    // which is a no-op for this shape (the hooks only concern\n    // FT.AGGREGATE/FT.CURSOR/SCAN and the remap only numeric aggregates —\n    // none of them default-keyed).\n    if (\n      requestPolicy === REQUEST_POLICIES_WITH_DEFAULTS.DEFAULT_KEYED &&\n      responsePolicy === RESPONSE_POLICIES_WITH_DEFAULTS.DEFAULT_KEYED\n    ) {\n      return this._execute(parser, readonly, options, makeFn(parser));\n    }\n\n    // https://redis.io/docs/latest/develop/reference/command-tips\n    const router = REQUEST_ROUTERS[requestPolicy];\n    if (!router) {\n      throw new Error(`Unknown request policy ${requestPolicy}`);\n    }\n    // Validated before any per-node promise is dispatched — throwing after\n    // would orphan in-flight rejections (unhandled-rejection noise) and run\n    // side effects for a reply that can never be reduced.\n    const reducer = RESPONSE_REDUCERS[responsePolicy];\n    if (!reducer) {\n      throw new Error(`Unknown response policy ${responsePolicy}`);\n    }\n    // Routers are typed against the erased base cluster types (routing is\n    // below the typed command surface); bridge this instantiation's slots in.\n    const plan = await router(\n      this._slots as unknown as Parameters<typeof router>[0],\n      parser,\n      readonly,\n      policy.keySpecs\n    );\n\n    if (plan.length === 0) {","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/redis/node-redis/blob/bb5beb56578573910e2ee8f39681edc214c41398/packages/client/lib/cluster/index.ts#L552-L588","documentation":"Thrown from RedisCluster._executeWithPolicies (cluster/index.ts:570) when the resolved request policy string has no entry in REQUEST_ROUTERS. REQUEST_ROUTERS covers all_nodes, all_shards, multi_shard, special, default-keyless, default-keyed; an unknown policy means the command-metadata resolver returned a request_policy tip the cluster does not know how to route.","triggerScenarios":"A custom command, module, or dynamically-resolved COMMAND tip yields a request policy string not in the router table (e.g. a new server tip the client version predates, or a malformed custom registration).","commonSituations":"Newer Redis server emitting a request_policy tip not yet supported by this client version; a hand-built custom command returning an arbitrary policy string; module commands with non-standard tips.","solutions":["Update the client to a version that supports the policy tip returned by the server.","For custom commands, ensure they resolve to a known policy (or no policy, which falls back to default-keyed/default-keyless).","Report the unknown policy string (it is interpolated in the message) to maintainers with the command and Redis version."],"exampleFix":"// no direct user API; mitigation is version alignment / custom-command policy fix:\n// before: custom module command resolves to request policy 'multi_node' (unsupported)\n// after: register the command without a policy so it falls back to default-keyed\nawait cluster.sendCommand(['MYCMD', 'key']);","handlingStrategy":"fallback","validationCode":null,"typeGuard":"function isUnknownRequestPolicy(e: unknown): boolean {\n  return e instanceof Error && /Unknown request policy/i.test(e.message);\n}","tryCatchPattern":"try { await cluster.sendCommand(cmd); }\ncatch (e) {\n  if (isUnknownRequestPolicy(e)) {\n    // fall back to routing to a single shard master directly\n    const node = await cluster.getSlotMaster(key);\n    return node.sendCommand(cmd);\n  }\n  throw e;\n}","preventionTips":["Keep client and server versions aligned for command tips.","Register custom commands without a policy to use the default route.","Capture the interpolated policy string when reporting the issue."],"tags":["cluster","command-metadata","internal","routing"],"analyzedSha":"bb5beb56578573910e2ee8f39681edc214c41398","analyzedAt":"2026-08-03T19:09:15.686Z","schemaVersion":2}