redis/node-redis · error · TypeError
topologyRefreshOnReconnectionAttempt must be undefined, fals
Error message
topologyRefreshOnReconnectionAttempt must be undefined, false, a non-negative integer, or a function
What it means
Thrown from ClusterReconnectionTracker.#validate (cluster-reconnection-tracker.ts:45), reached via the constructor, which RedisClusterSlots calls at cluster construction. The topologyRefreshOnReconnectionAttemptStrategy option must be undefined, false, a non-negative integer, or a function; anything else (string, negative/float number, true, object) is rejected up front with a TypeError.
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 bb5beb5657)
Solutions
- Pass one of: undefined (default 5s), false or 0 (disable), a non-negative integer (ms delay), or a function.
- When loading from env, coerce with Number() and validate Number.isInteger(n) && n >= 0 before passing.
- If a float was intended, round it: Math.round(value).
Example fix
// before
const cluster = createCluster({
rootNodes: [{ socket: { host: 'h', port: 7000 } }],
topologyRefreshOnReconnectionAttemptStrategy: '5000' // string -> TypeError
});
// after
const delay = Number(process.env.TOPO_REFRESH_DELAY);
const cluster = createCluster({
rootNodes: [{ socket: { host: 'h', port: 7000 } }],
topologyRefreshOnReconnectionAttemptStrategy: Number.isInteger(delay) && delay >= 0 ? delay : undefined
}); Defensive patterns
Strategy: validation
Validate before calling
function normalizeStrategy(v: unknown) {
if (v === undefined || v === false || typeof v === 'function') return v;
if (typeof v === 'number' && Number.isInteger(v) && v >= 0) return v;
throw new TypeError('invalid topologyRefreshOnReconnectionAttemptStrategy');
}
const cluster = createCluster({ rootNodes, topologyRefreshOnReconnectionAttemptStrategy: normalizeStrategy(raw) }); Type guard
function isStrategy(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
- Validate config-derived values before passing them in.
- Coerce env strings with Number() and check Number.isInteger && >= 0.
- Pass undefined to accept the documented 5s default.
When it happens
Trigger: Constructing createCluster({ topologyRefreshOnReconnectionAttemptStrategy: <invalid> }) — e.g. passing '5000' (string), -1, 1.5, true, or {}.
Common situations: Loading config from env/JSON where numbers arrive as strings; passing a float delay; misreading the docs and passing true to 'enable'.
Related errors
- topologyRefreshOnReconnectionAttempt should return `false |
- Reconnect strategy should return `false | Error | number`, g
- Client Side Caching is only supported with RESP3
- Client Side Caching is only supported with RESP3
- invalid nodeClientOptions for Sentinel
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/9a3da0410a3d87c9.json.
Report an issue: GitHub.