{"record":{"id":"a247cc57741aff41","repo":"discordjs/discord.js","slug":"no-worker-found-for-shard-shardid","errorCode":null,"errorMessage":"No worker found for shard ${shardId}","messagePattern":"No worker found for shard (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts","lineNumber":182,"sourceCode":"\t\t\t\t// eslint-disable-next-line no-promise-executor-return, promise/prefer-await-to-then\n\t\t\t\tnew Promise<void>((resolve) => this.destroyPromises.set(shardId, resolve)).then(async () => worker.terminate()),\n\t\t\t);\n\t\t\tworker.postMessage(payload);\n\t\t}\n\n\t\tthis.#workers = [];\n\t\tthis.#workerByShardId.clear();\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.send}\n\t */\n\tpublic send(shardId: number, data: GatewaySendPayload) {\n\t\tconst worker = this.#workerByShardId.get(shardId);\n\t\tif (!worker) {\n\t\t\tthrow new Error(`No worker found for shard ${shardId}`);\n\t\t}\n\n\t\tconst payload: WorkerSendPayload = {\n\t\t\top: WorkerSendPayloadOp.Send,\n\t\t\tshardId,\n\t\t\tpayload: data,\n\t\t};\n\t\tworker.postMessage(payload);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.fetchStatus}\n\t */\n\tpublic async fetchStatus() {\n\t\tconst statuses = new Collection<number, WebSocketShardStatus>();\n\n\t\tfor (const [shardId, worker] of this.#workerByShardId.entries()) {\n\t\t\tconst nonce = Math.random();","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/ws/src/strategies/sharding/WorkerShardingStrategy.ts#L164-L200","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait manager.send(shardId, { op: GatewayOpcodes.PresenceUpdate, ... });\n// after\nawait manager.spawn();\nif (shardId >= 0 && shardId < manager.totalShards) {\n  await manager.send(shardId, { op: GatewayOpcodes.PresenceUpdate, ... });\n}","handlingStrategy":"try-catch","validationCode":"// With worker sharding, ensure spawn completed first:\nawait manager.spawn();\nconst total = manager.options.shardCount ?? 1;\nif (!(shardId >= 0 && shardId < total)) {\n  throw new RangeError(`shardId ${shardId} outside 0..${total - 1}`);\n}","typeGuard":"const shardInRange = (id, total) => Number.isInteger(id) && id >= 0 && id < total;","tryCatchPattern":"try {\n  await manager.send(shardId, payload);\n} catch (err) {\n  if (err instanceof Error && /No worker found for shard/.test(err.message)) {\n    console.error(`No worker owns shard ${shardId}; did you await manager.spawn()?`);\n  } else throw err;\n}","preventionTips":["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."],"tags":["discord","websocket","sharding","worker-threads"],"backgroundTag":"shard-not-found","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}