{"record":{"id":"9a460f309e910bc5","repo":"discordjs/discord.js","slug":"shard-shardid-does-not-exist","errorCode":null,"errorMessage":"Shard ${shardId} does not exist","messagePattern":"Shard (.+?) does not exist","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/ws/src/utils/WorkerBootstrapper.ts","lineNumber":57,"sourceCode":"\n\t/**\n\t * The shards that are managed by this worker\n\t */\n\tprotected readonly shards = new Collection<number, WebSocketShard>();\n\n\tpublic constructor() {\n\t\tif (isMainThread) {\n\t\t\tthrow new Error('Expected WorkerBootstrap to not be used within the main thread');\n\t\t}\n\t}\n\n\t/**\n\t * Helper method to initiate a shard's connection process\n\t */\n\tprotected async connect(shardId: number): Promise<void> {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} does not exist`);\n\t\t}\n\n\t\tawait shard.connect();\n\t}\n\n\t/**\n\t * Helper method to destroy a shard\n\t */\n\tprotected async destroy(shardId: number, options?: WebSocketShardDestroyOptions): Promise<void> {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} does not exist`);\n\t\t}\n\n\t\tawait shard.destroy(options);\n\t}\n\n\t/**","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/ws/src/utils/WorkerBootstrapper.ts#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (main thread sends connect for shard outside worker range)\nworker.postMessage({ op: ConnectWorker, shardId: 5 });\n// after\nconst range = getShardsForWorker(workerId); // e.g. [5,6]\nif (range.includes(5)) {\n  worker.postMessage({ op: ConnectWorker, shardId: 5 });\n}","handlingStrategy":"validation","validationCode":"// Before asking a worker to connect a shard, ensure that worker spawned it:\nfunction workerOwnsShard(shardId, workerShardRanges) {\n  return workerShardRanges.some(([start, end]) => shardId >= start && shardId <= end);\n}\nif (!workerOwnsShard(shardId, assignedRanges)) {\n  throw new RangeError(`Worker does not own shard ${shardId}`);\n}","typeGuard":"const ownsShard = (id, range) => typeof id === 'number' && id >= range.start && id <= range.end;","tryCatchPattern":"try {\n  await bootstrapper.connect(shardId);\n} catch (err) {\n  if (err instanceof RangeError && err.message.includes('does not exist')) {\n    console.error(`Shard ${shardId} was never spawned in this worker; check shard range assignment`);\n  } else throw err;\n}","preventionTips":["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."],"tags":["discord","websocket","sharding","worker-threads","range-error"],"backgroundTag":"shard-not-found","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}