discordjs/discord.js · error · Error
No worker found for shard ${shardId}
Error message
No worker found for shard ${shardId} What it means
WorkerShardingStrategy.send maps shardId to a worker via its #workerByShardId map and throws if no worker manages that shard. The mapping is populated during fetchShards/spawn, so an unmapped id means the shard was never assigned to any worker. Unlike SimpleShardingStrategy this throws a plain Error because the strategy has no direct shard objects to look up.
Source
Thrown at packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts:182
// eslint-disable-next-line no-promise-executor-return, promise/prefer-await-to-then
new Promise<void>((resolve) => this.destroyPromises.set(shardId, resolve)).then(async () => worker.terminate()),
);
worker.postMessage(payload);
}
this.#workers = [];
this.#workerByShardId.clear();
await Promise.all(promises);
}
/**
* {@inheritDoc IShardingStrategy.send}
*/
public send(shardId: number, data: GatewaySendPayload) {
const worker = this.#workerByShardId.get(shardId);
if (!worker) {
throw new Error(`No worker found for shard ${shardId}`);
}
const payload: WorkerSendPayload = {
op: WorkerSendPayloadOp.Send,
shardId,
payload: data,
};
worker.postMessage(payload);
}
/**
* {@inheritDoc IShardingStrategy.fetchStatus}
*/
public async fetchStatus() {
const statuses = new Collection<number, WebSocketShardStatus>();
for (const [shardId, worker] of this.#workerByShardId.entries()) {
const nonce = Math.random();View on GitHub (pinned to a81ed8a306)
Solutions
- Await manager.spawn() (strategy.fetchShards) before sending any payloads so the worker-to-shard map is populated.
- Validate shardId against the configured shardCount/shardIds before calling send.
- If workers were killed, respawn via the manager instead of sending to stale ids.
Example fix
// before
await manager.send(shardId, { op: GatewayOpcodes.PresenceUpdate, ... });
// after
await manager.spawn();
if (shardId >= 0 && shardId < manager.totalShards) {
await manager.send(shardId, { op: GatewayOpcodes.PresenceUpdate, ... });
} Defensive patterns
Strategy: try-catch
Validate before calling
// With worker sharding, ensure spawn completed first:
await manager.spawn();
const total = manager.options.shardCount ?? 1;
if (!(shardId >= 0 && shardId < total)) {
throw new RangeError(`shardId ${shardId} outside 0..${total - 1}`);
} Type guard
const shardInRange = (id, total) => Number.isInteger(id) && id >= 0 && id < total;
Try / catch
try {
await manager.send(shardId, payload);
} catch (err) {
if (err instanceof Error && /No worker found for shard/.test(err.message)) {
console.error(`No worker owns shard ${shardId}; did you await manager.spawn()?`);
} else throw err;
} Prevention
- Await manager.spawn() before any send when using WorkerShardingStrategy.
- Match shardCount/shardIds options with ids used in sends after any reshard.
- Do not send to workers after they have been terminated without respawning.
When it happens
Trigger: Calling send(shardId, payload) through the WebSocketManager while using the worker sharding strategy before spawn() has populated the worker map, with an out-of-range shardId, or after workers were destroyed/respawned and the map was cleared.
Common situations: Using WorkerShardingStrategy (workers: N > 0) with code written against the simple strategy that sends immediately at startup without awaiting spawn; mismatched shardIds computed from a different shard count; process restarts where spawn was skipped.
Related errors
- Shard ${shardId} does not exist
- Shard ${shardId} not found
- ShardingWorkerExists
- Shard ${payload.shardId} does not exist
- WebSocketShard: transport compression is enabled, disabling
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/a247cc57741aff41.
Report an issue: GitHub.