discordjs/discord.js · error · DiscordjsError

ShardingWorkerExists

ShardingWorkerExists

Error message

ShardingWorkerExists

What it means

ShardingWorkerExists is thrown by Shard.spawn() when the shard already has a live Worker thread attached (this.worker is set). It is the worker-mode counterpart of ShardingProcessExists and prevents starting a second worker thread for the same shard, which would break IPC message routing.

Source

Thrown at packages/discord.js/src/sharding/Shard.js:143

     * Listener function for the {@link ChildProcess}' `exit` event
     *
     * @type {Function}
     * @private
     */
    this._exitListener = null;
  }

  /**
   * Forks a child process or creates a worker thread for the shard.
   * <warn>You should not need to call this manually.</warn>
   *
   * @param {number} [timeout=30000] The amount in milliseconds to wait until the {@link Client} has become ready
   * before resolving (`-1` or `Infinity` for no wait)
   * @returns {Promise<ChildProcess>}
   */
  async spawn(timeout = 30_000) {
    if (this.process) throw new DiscordjsError(ErrorCodes.ShardingProcessExists, this.id);
    if (this.worker) throw new DiscordjsError(ErrorCodes.ShardingWorkerExists, this.id);

    this._exitListener = this._handleExit.bind(this, undefined, timeout);

    switch (this.manager.mode) {
      case 'process':
        this.process = childProcess
          .fork(path.resolve(this.manager.file), this.args, {
            env: this.env,
            execArgv: this.execArgv,
            silent: this.silent,
          })
          .on('message', this._handleMessage.bind(this))
          .on('exit', this._exitListener);
        break;
      case 'worker':
        this.worker = new Worker(path.resolve(this.manager.file), {
          workerData: this.env,
          env: SHARE_ENV,

View on GitHub (pinned to a81ed8a306)

Solutions

  1. Check shard.worker is null/undefined before spawning
  2. Await the previous spawn/exit (or call respawn()) instead of spawning again
  3. Tear down the old ShardingManager (kill workers) before creating and spawning a new one
  4. Avoid spawning the same manager from multiple entry points (e.g., both main and a warmup module)

Example fix

// before
if (shouldRestart) manager.spawn(); // throws ShardingWorkerExists
// after
if (shouldRestart) await Promise.all(manager.shards.map(s => s.respawn()));
Defensive patterns

Strategy: validation

Validate before calling

function canSpawnWorker(shard) { return shard.worker == null && shard.process == null; }
if (canSpawnWorker(shard)) await shard.spawn();

Type guard

function hasLiveWorker(shard) { return shard.worker != null; }

Try / catch

try {
  await shard.spawn();
} catch (err) {
  if (err.code === 'ShardingWorkerExists') {
    return shard.worker; // worker already live
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling spawn() on a shard whose manager.mode is 'worker' while this.worker is still set; calling manager.spawn() twice; concurrent respawn()/spawn() calls racing past the guard; spawning after a previous spawn() that hasn't exited.

Common situations: Using ShardingManager with mode:'worker' and re-running the bootstrap script (e.g., PM2 or nodemon restart logic that doesn't kill the manager); hot-reload wrappers that re-instantiate manager.spawn() without tearing down the old manager.

Related errors


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