discordjs/discord.js · error · DiscordjsError

ShardingProcessExists

ShardingProcessExists

Error message

ShardingProcessExists

What it means

ShardingProcessExists is thrown by Shard.spawn() when a shard already has a live child process attached (this.process is set). discord.js guards spawn() to prevent launching a second ChildProcess for the same shard, which would orphan the first and corrupt manager state. Each Shard must have at most one process in 'process' mode.

Source

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

    /**
     * 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,

View on GitHub (pinned to a81ed8a306)

Solutions

  1. Check shard.process is null/undefined before calling spawn(), or rely on manager.spawn() which skips already-spawned shards
  2. Use await shard.respawn() instead of a raw spawn() when you intend to restart - it kills the existing child first
  3. Ensure the previous spawn()/process exit is fully awaited before re-spawning (await the promise, don't fire-and-forget)
  4. If the process handle is stale after a crash, remove the exit listener and set shard.process = null before respawning

Example fix

// before
for (const shard of manager.shards) {
  shard.spawn(); // throws ShardingProcessExists on running shards
}
// after
for (const shard of manager.shards) {
  if (!shard.process) await shard.spawn();
}
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

function isSpawnable(shard) { return !('process' in shard && shard.process) && !('worker' in shard && shard.worker); }

Try / catch

try {
  await shard.spawn();
} catch (err) {
  if (err.code === 'ShardingProcessExists' || err.name === 'DiscordjsError' && /ShardingProcessExists/.test(err.message)) {
    return shard.process; // already running
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling manager.spawn() or shard.spawn() while the shard's process is already running; calling spawn() again after a previous spawn() resolved without the process exiting; manually invoking respawn() concurrently with spawn() so both pass the guard check in a race.

Common situations: Double-invoking ShardingManager.spawn() (e.g., an init routine running twice on hot reload); awaiting respawn() while the old process has not fully exited; custom orchestration code calling spawn() per shard inside an interval without checking shard.process.

Related errors


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