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
- Check shard.process is null/undefined before calling spawn(), or rely on manager.spawn() which skips already-spawned shards
- Use await shard.respawn() instead of a raw spawn() when you intend to restart - it kills the existing child first
- Ensure the previous spawn()/process exit is fully awaited before re-spawning (await the promise, don't fire-and-forget)
- 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
- Prefer manager.spawn() / shard.respawn() over raw spawn() for restarts
- Guard with shard.process/shard.worker checks before spawning
- Never spawn the same ShardingManager from two code paths
- Track spawn state in your own orchestrator and treat spawn as idempotent
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
- ShardingWorkerExists
- ShardingNoChildExists
- ShardingShardMiscalculation
- ClientInvalidOption
- Shard ${shardId} not found
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/55c65629ed8d8312.
Report an issue: GitHub.