discordjs/discord.js · error · RangeError

Shard ${shardId} not found

Error message

Shard ${shardId} not found

What it means

SimpleShardingStrategy.send looks up the shard in its internal shards Collection before forwarding a gateway payload. If the shardId is not present, the shard was never spawned/registered, so it throws a RangeError rather than silently dropping the payload. This guards against sending to shards that do not exist in the current sharding configuration.

Source

Thrown at packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts:73

	 */
	public async destroy(options?: Omit<WebSocketShardDestroyOptions, 'recover'>) {
		const promises = [];

		for (const shard of this.shards.values()) {
			promises.push(shard.destroy(options));
		}

		await Promise.all(promises);
		this.shards.clear();
	}

	/**
	 * {@inheritDoc IShardingStrategy.send}
	 */
	public async send(shardId: number, payload: GatewaySendPayload) {
		const shard = this.shards.get(shardId);
		if (!shard) {
			throw new RangeError(`Shard ${shardId} not found`);
		}

		return shard.send(payload);
	}

	/**
	 * {@inheritDoc IShardingStrategy.fetchStatus}
	 */
	public async fetchStatus() {
		return this.shards.mapValues((shard) => shard.status);
	}
}

View on GitHub (pinned to a81ed8a306)

Solutions

  1. Ensure the shard is spawned (await manager.spawn()) before sending to that shardId.
  2. Verify shardId is within 0..totalShards-1 matching your configured shardCount/shardIds.
  3. Handle GatewaySendPayloads that must go to all shards by fetching the current shard id set instead of hardcoding ids.

Example fix

// before
await manager.send(99, payload);
// after
if (manager.shardIds.includes(99)) {
  await manager.send(99, payload);
} else {
  throw new Error(`Shard 99 is not spawned; valid: ${[...manager.shardIds]}`);
}
Defensive patterns

Strategy: validation

Validate before calling

const totalShards = manager.options.retrieveTotalShards ? await manager.options.retrieveTotalShards() : manager.options.shardCount;
function canSend(shardId) {
  return Number.isInteger(shardId) && shardId >= 0 && shardId < totalShards;
}
if (!canSend(shardId)) throw new RangeError(`Refusing to send: shard ${shardId} out of range`);

Type guard

const isValidShardId = (id, total) => typeof id === 'number' && Number.isInteger(id) && id >= 0 && id < total;

Try / catch

try {
  await manager.send(shardId, payload);
} catch (err) {
  if (err instanceof RangeError && err.message.startsWith('Shard')) {
    console.warn(`Shard ${shardId} missing; spawning before retry`);
    await manager.spawn();
    await manager.send(shardId, payload);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling WebSocketManager's send(shardId, payload) (which delegates to this strategy) with a shardId that was never spawned, or after the strategy was created with a shard count that excludes that id, or before/after shard spawn lifecycle events.

Common situations: Sending an IDENTIFY/PRESENCE_UPDATE to an out-of-range shard id; totalShards configured lower than the ids your code computes; bot grew to more shards and cached/hardcoded shard ids are stale; resharding replaced strategy instances.

Related errors


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