mongodb/node-mongodb-native · critical · MongoRuntimeError
illegal state transition from [${target.s.state}] => [${newS
Error message
illegal state transition from [${target.s.state}] => [${newState}], allowed: [${legalStates}] What it means
Thrown by the state machine produced by makeStateMachine() when a requested transition (e.g. CONNECTING => CONNECTED) is not listed as legal from the current state. The driver uses three such machines (topology.ts, server.ts, monitor.ts) to enforce the SDAM lifecycle. Hitting this means the driver attempted an out-of-order lifecycle change, which is an internal invariant violation rather than normal user input. It surfaces as a MongoRuntimeError.
Source
Thrown at src/utils.ts:426
s: { state: string };
emit(event: 'stateChanged', state: string, newState: string): void;
}
interface StateTransitionFunction {
(target: ObjectWithState, newState: string): void;
}
/** @public */
export type EventEmitterWithState = {
/** @internal */
stateChanged(previous: string, current: string): void;
};
/** @internal */
export function makeStateMachine(stateTable: StateTable): StateTransitionFunction {
return function stateTransition(target, newState) {
const legalStates = stateTable[target.s.state];
if (legalStates && legalStates.indexOf(newState) < 0) {
throw new MongoRuntimeError(
`illegal state transition from [${target.s.state}] => [${newState}], allowed: [${legalStates}]`
);
}
target.emit('stateChanged', target.s.state, newState);
target.s.state = newState;
};
}
/**
* This function returns the number of milliseconds since an arbitrary point in time.
* This function should only be used to measure time intervals.
* @internal
* */
export function processTimeMS(): number {
return Math.floor(performance.now());
}
View on GitHub (pinned to 3366c21a63)
Solutions
- Call connect() exactly once per MongoClient and do not re-connect on an already-connected client; rely on a singleton.
- Serialize lifecycle calls: never call close() concurrently with connect(); await both fully.
- After any fatal connection error, create a fresh MongoClient rather than retrying connect() on the same instance.
- If this reproduces deterministically, capture the from/to states in the message and report it as a driver bug with a minimal repro.
Example fix
// before
await client.connect();
// ... later, another path:
await client.connect(); // illegal transition if already connected
// after
if (!client.isConnected()) {
await client.connect();
} Defensive patterns
Strategy: try-catch
Try / catch
try {
if (!client.isConnected()) await client.connect();
} catch (err) {
if (err instanceof MongoRuntimeError && /illegal state transition/.test(err.message)) {
// abandon this client and build a fresh one
client = new MongoClient(uri);
await client.connect();
} else {
throw err;
}
} Prevention
- Call connect() exactly once per MongoClient instance; guard with isConnected().
- Never run connect() and close() concurrently on the same client.
- After a fatal connection error, create a new MongoClient instead of reconnecting.
When it happens
Trigger: Concurrent lifecycle calls racing against each other: calling connect() while a connect() is in flight, calling close() while connect() is still connecting, or connect() being invoked on an already-connected client/server/monitor. Also seen after a previous error left an object in an unexpected state.
Common situations: Calling `await client.connect()` twice without close(); invoking operations that internally connect while the application also explicitly connects; using the same MongoClient across workers/forks after the topology is partially torn down; race between request handlers triggering close() and new requests triggering connect().
Related errors
- ConnectionPool.clear() called in load balanced mode with no
- Service generations are required in load balancer mode.
- Unexpected null session. A cursor creating command should ha
- ServerDescription must be provided with a non-empty address
- unexpected topology type: ${topologyDescription.type} (this
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/91ead02f90d628e5.json.
Report an issue: GitHub.