discordjs/discord.js · error · Error
Not enough sessions remaining to spawn ${shardIds.length} sh
Error message
Not enough sessions remaining to spawn ${shardIds.length} shards; only ${data.session_start_limit.remaining} remaining; resets at ${new Date(Date.now() + data.session_start_limit.reset_after).toISOString()} What it means
Before spawning shards, the manager checks Discord's session_start_limit. If the remaining identify sessions are fewer than the number of shards to spawn, it throws, because connecting would exceed Discord's rate limit on new sessions. The message includes the reset time.
Source
Thrown at packages/ws/src/ws/WebSocketManager.ts:364
} else {
const data = await this.fetchGatewayInformation();
shardIds = [...range(this.options.shardCount ?? data.shards)];
}
this.shardIds = shardIds;
return shardIds;
}
public async connect() {
const shardCount = await this.getShardCount();
// Spawn shards and adjust internal state
await this.updateShardCount(shardCount);
const shardIds = await this.getShardIds();
const data = await this.fetchGatewayInformation();
if (data.session_start_limit.remaining < shardIds.length) {
throw new Error(
`Not enough sessions remaining to spawn ${shardIds.length} shards; only ${
data.session_start_limit.remaining
} remaining; resets at ${new Date(Date.now() + data.session_start_limit.reset_after).toISOString()}`,
);
}
await this.strategy.connect();
}
public setToken(token: string): void {
if (this.#token) {
throw new Error('Token has already been set');
}
this.#token = token;
}
public destroy(options?: Omit<WebSocketShardDestroyOptions, 'recover'>) {View on GitHub (pinned to a81ed8a306)
Solutions
- Wait until the session limit resets (time given in the error message) before reconnecting
- Reduce the number of shards spawned per attempt; connect them in batches as the limit replenishes
- Avoid unnecessary full restarts — use resume/reconnect logic instead of fresh identifies
- Check session_start_limit via fetchGatewayInformation before planning a shard scale-up
Example fix
// before
await manager.connect();
// after
const info = await rest.get(Routes.gatewayBot());
if (info.session_start_limit.remaining < manager.getShardCount()) {
const waitMs = info.session_start_limit.reset_after;
console.log(`Waiting ${waitMs}ms for session limit reset`);
await new Promise((r) => setTimeout(r, waitMs));
}
await manager.connect(); Defensive patterns
Strategy: retry
Validate before calling
const info = await rest.get(Routes.gatewayBot());
if (info.session_start_limit.remaining < shardCount) {
console.warn(`Only ${info.session_start_limit.remaining} sessions left; resets at ${new Date(Date.now() + info.session_start_limit.reset_after)}`);
} Try / catch
try {
await manager.connect();
} catch (e) {
if (e instanceof Error && e.message.includes('Not enough sessions remaining')) {
await new Promise((r) => setTimeout(r, resetAfterMs));
await manager.connect();
} else throw e;
} Prevention
- Check session_start_limit before every full restart or shard scale-up
- Avoid rapid restart loops in development on large sharded bots
- Batch shard connections to stay within the identify budget
When it happens
Trigger: Calling manager.connect() (or strategy.connect() via updateShardCount path) when data.session_start_limit.remaining < shardIds.length — typically after repeated bot restarts within the reset window.
Common situations: Frequent dev-mode restarts of a large bot burning identify sessions; scaling up shard count beyond remaining sessions; multiple processes sharing one token each identifying many shards.
Related errors
- Request timed out
- InteractionAlreadyReplied
- InteractionNotReplied
- HTTPError(status, res.statusText, method, url, requestData)
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/f6b6d48090858a7b.
Report an issue: GitHub.