discordjs/discord.js · error · RangeError
Shard ${shardId} does not exist
Error message
Shard ${shardId} does not exist What it means
WorkerBootstrapper.connect retrieves the WebSocketShard for the given shardId from its shards Collection and throws a RangeError if it is absent, then awaits shard.connect(). It is invoked when the main thread sends a Connect/ShardIdentify payload, so an unmapped id means the worker was told to spawn/connect a shard it does not own. This indicates a mismatch between the shard ranges assigned by the main thread and what this worker actually spawned.
Source
Thrown at packages/ws/src/utils/WorkerBootstrapper.ts:57
/**
* The shards that are managed by this worker
*/
protected readonly shards = new Collection<number, WebSocketShard>();
public constructor() {
if (isMainThread) {
throw new Error('Expected WorkerBootstrap to not be used within the main thread');
}
}
/**
* Helper method to initiate a shard's connection process
*/
protected async connect(shardId: number): Promise<void> {
const shard = this.shards.get(shardId);
if (!shard) {
throw new RangeError(`Shard ${shardId} does not exist`);
}
await shard.connect();
}
/**
* Helper method to destroy a shard
*/
protected async destroy(shardId: number, options?: WebSocketShardDestroyOptions): Promise<void> {
const shard = this.shards.get(shardId);
if (!shard) {
throw new RangeError(`Shard ${shardId} does not exist`);
}
await shard.destroy(options);
}
/**View on GitHub (pinned to a81ed8a306)
Solutions
- Make sure spawnShards was completed for this worker with the exact shardId range the main thread will request connect for.
- Reconcile shardId assignments between main thread and workers (same totalShards and range formula) after resharding.
- Check that the worker message payloads (shardId) come from the manager's computed range, not hardcoded values.
Example fix
// before (main thread sends connect for shard outside worker range)
worker.postMessage({ op: ConnectWorker, shardId: 5 });
// after
const range = getShardsForWorker(workerId); // e.g. [5,6]
if (range.includes(5)) {
worker.postMessage({ op: ConnectWorker, shardId: 5 });
} Defensive patterns
Strategy: validation
Validate before calling
// Before asking a worker to connect a shard, ensure that worker spawned it:
function workerOwnsShard(shardId, workerShardRanges) {
return workerShardRanges.some(([start, end]) => shardId >= start && shardId <= end);
}
if (!workerOwnsShard(shardId, assignedRanges)) {
throw new RangeError(`Worker does not own shard ${shardId}`);
} Type guard
const ownsShard = (id, range) => typeof id === 'number' && id >= range.start && id <= range.end;
Try / catch
try {
await bootstrapper.connect(shardId);
} catch (err) {
if (err instanceof RangeError && err.message.includes('does not exist')) {
console.error(`Shard ${shardId} was never spawned in this worker; check shard range assignment`);
} else throw err;
} Prevention
- Ensure every shardConnect/spawn message from the main thread targets a shard the worker actually spawned.
- Keep the shard-to-worker range formula identical on both sides after totalShards changes.
- Complete spawnShards for all workers before sending ConnectWorker messages.
When it happens
Trigger: The main thread sends a ConnectWorker/ShardIdentify message for a shardId this worker never spawned (outside its assigned range), or the spawn step for that shard was skipped/failed before connect was requested.
Common situations: Total shard count changed (scale up/down) so the main thread's shard-to-worker assignment no longer matches workers' local shards; custom sharding logic computing ranges inconsistently; manual communication with the bootstrapper's message handler using wrong ids.
Related errors
- Shard ${shardId} not found
- No worker found for shard ${shardId}
- Shard ${payload.shardId} does not exist
- ShardingWorkerExists
- WebSocketShard: transport compression is enabled, disabling
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/9a460f309e910bc5.
Report an issue: GitHub.