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

  1. Make sure spawnShards was completed for this worker with the exact shardId range the main thread will request connect for.
  2. Reconcile shardId assignments between main thread and workers (same totalShards and range formula) after resharding.
  3. 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

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


AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30). Data as JSON: /api/errors/9a460f309e910bc5. Report an issue: GitHub.