{"record":{"id":"b5112c267ef4bb4a","repo":"discordjs/discord.js","slug":"shard-shardid-not-found","errorCode":null,"errorMessage":"Shard ${shardId} not found","messagePattern":"Shard (.+?) not found","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts","lineNumber":73,"sourceCode":"\t */\n\tpublic async destroy(options?: Omit<WebSocketShardDestroyOptions, 'recover'>) {\n\t\tconst promises = [];\n\n\t\tfor (const shard of this.shards.values()) {\n\t\t\tpromises.push(shard.destroy(options));\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t\tthis.shards.clear();\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.send}\n\t */\n\tpublic async send(shardId: number, payload: GatewaySendPayload) {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} not found`);\n\t\t}\n\n\t\treturn shard.send(payload);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.fetchStatus}\n\t */\n\tpublic async fetchStatus() {\n\t\treturn this.shards.mapValues((shard) => shard.status);\n\t}\n}\n","sourceCodeStart":55,"sourceCodeEnd":86,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts#L55-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the shard is spawned (await manager.spawn()) before sending to that shardId.","Verify shardId is within 0..totalShards-1 matching your configured shardCount/shardIds.","Handle GatewaySendPayloads that must go to all shards by fetching the current shard id set instead of hardcoding ids."],"exampleFix":"// before\nawait manager.send(99, payload);\n// after\nif (manager.shardIds.includes(99)) {\n  await manager.send(99, payload);\n} else {\n  throw new Error(`Shard 99 is not spawned; valid: ${[...manager.shardIds]}`);\n}","handlingStrategy":"validation","validationCode":"const totalShards = manager.options.retrieveTotalShards ? await manager.options.retrieveTotalShards() : manager.options.shardCount;\nfunction canSend(shardId) {\n  return Number.isInteger(shardId) && shardId >= 0 && shardId < totalShards;\n}\nif (!canSend(shardId)) throw new RangeError(`Refusing to send: shard ${shardId} out of range`);","typeGuard":"const isValidShardId = (id, total) => typeof id === 'number' && Number.isInteger(id) && id >= 0 && id < total;","tryCatchPattern":"try {\n  await manager.send(shardId, payload);\n} catch (err) {\n  if (err instanceof RangeError && err.message.startsWith('Shard')) {\n    console.warn(`Shard ${shardId} missing; spawning before retry`);\n    await manager.spawn();\n    await manager.send(shardId, payload);\n  } else throw err;\n}","preventionTips":["Always await manager.spawn() before sending payloads.","Derive shard ids from the manager's configuration, never hardcode them.","Track resharding events and invalidate cached shard ids."],"tags":["discord","websocket","sharding","range-error"],"backgroundTag":"shard-not-found","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}