redis/node-redis · error · TypeError
topologyRefreshOnReconnectionAttempt must be undefined…
Error message
topologyRefreshOnReconnectionAttempt must be undefined, false, a non-negative integer, or a function
What it means
Thrown by ClusterReconnectionTracker constructor validation when the topologyRefreshOnReconnectionAttemptStrategy option is not one of: undefined, false, a non-negative integer, or a function. The strategy controls when a cluster topology refresh is triggered after a node starts reconnecting; an invalid type is rejected at client construction time.
Solutions
- Pass undefined (default 5s), false or 0 (disabled), a non-negative integer (ms delay), or a function.
- If reading from env/config, coerce with Number() and validate Number.isInteger(v) && v >= 0 before passing.
- Pass a function (firstReconnectionAt) => delay for custom logic instead of a value.
- Do not pass true; use undefined for the default-enabled behavior.
Example fix
// before
const cluster = createCluster({ rootNodes, topologyRefreshOnReconnectionAttemptStrategy: '5000' });
// TypeError at construction
// after
const cluster = createCluster({ rootNodes, topologyRefreshOnReconnectionAttemptStrategy: 5000 }); Defensive patterns
Strategy: validation
Validate before calling
function validateTopologyStrategy(v: unknown): void {
if (v === undefined || v === false || typeof v === 'function' ||
(typeof v === 'number' && Number.isInteger(v) && v >= 0)) return;
throw new TypeError('Invalid topologyRefreshOnReconnectionAttemptStrategy');
}
validateTopologyStrategy(configValue); Type guard
function isTopologyStrategy(v: unknown): v is undefined | false | number | ((t: number) => false | undefined | number) {
return v === undefined || v === false || typeof v === 'function' ||
(typeof v === 'number' && Number.isInteger(v) && v >= 0);
} Prevention
- Pass undefined, false, a non-negative integer, or a function only.
- Coerce env-string values with Number() and validate integer >= 0 before passing.
- Do not pass true; use undefined for default behavior.
When it happens
Trigger: Passing cluster option topologyRefreshOnReconnectionAttemptStrategy as a string ('5000'), a negative number (-1), a float (5.5), or an object. Passing it as a boolean true (only false is accepted).
Common situations: Reading the delay from an environment variable as a string and passing it uncoerced; passing a float milliseconds value; copy-paste from docs that showed a function but leaving stray characters; passing true expecting it to mean 'enabled'.
Related errors
- topologyRefreshOnReconnectionAttempt should return `false |…
- Reconnect strategy should return `false | Error | number`…
- Cannot split : key region does not align with keystep
- Cannot split : key region overruns the arguments
- Client Side Caching is only supported with RESP3
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/9a3da0410a3d87c9.
Report an issue: GitHub.
Appendix: source
Thrown at packages/client/lib/cluster/cluster-reconnection-tracker.ts:45
/**
* Validates that a strategy value is acceptable before use.
* @throws If the strategy is not supported
*/
#validate(strategy?: ClusterTopologyRefreshOnReconnectionAttemptStrategy) {
if (
strategy === undefined ||
strategy === false ||
typeof strategy === 'function' ||
(
typeof strategy === 'number' &&
Number.isInteger(strategy) &&
strategy >= 0
)
) {
return;
}
throw new TypeError('topologyRefreshOnReconnectionAttempt must be undefined, false, a non-negative integer, or a function');
}
constructor(strategy?: ClusterTopologyRefreshOnReconnectionAttemptStrategy) {
this.#validate(strategy);
this.#strategy = strategy;
}
get reconnectingAddresses() {
return new Set(this.#reconnectingClients.values());
}
get firstReconnectionAt() {
return this.#firstReconnectionAt;
}
/**
* Records a reconnection attempt for the given client and evaluates whether
* the configured delay has elapsed since the first attempt in this cycle.View on GitHub (pinned to 90fd0652bc)