discordjs/discord.js · error · Error

Token has already been set

Error message

Token has already been set

What it means

setToken() refuses to overwrite an existing token and throws if this.#token is already set. The manager treats the token as immutable once configured to prevent inconsistent auth state across shards.

Source

Thrown at packages/ws/src/ws/WebSocketManager.ts:376

		await this.updateShardCount(shardCount);

		const shardIds = await this.getShardIds();
		const data = await this.fetchGatewayInformation();

		if (data.session_start_limit.remaining < shardIds.length) {
			throw new Error(
				`Not enough sessions remaining to spawn ${shardIds.length} shards; only ${
					data.session_start_limit.remaining
				} remaining; resets at ${new Date(Date.now() + data.session_start_limit.reset_after).toISOString()}`,
			);
		}

		await this.strategy.connect();
	}

	public setToken(token: string): void {
		if (this.#token) {
			throw new Error('Token has already been set');
		}

		this.#token = token;
	}

	public destroy(options?: Omit<WebSocketShardDestroyOptions, 'recover'>) {
		return this.strategy.destroy(options);
	}

	public send(shardId: number, payload: GatewaySendPayload) {
		return this.strategy.send(shardId, payload);
	}

	public fetchStatus(): Awaitable<Collection<number, WebSocketShardStatus>> {
		return this.strategy.fetchStatus();
	}

	public async [Symbol.asyncDispose]() {

View on GitHub (pinned to a81ed8a306)

Solutions

  1. Call setToken only once, at initialization
  2. Destroy the existing manager and create a new one if the token must change
  3. Guard the call: only setToken if no token was set yet (token getter throws when unset, so track it yourself)

Example fix

// before
manager.setToken(newToken); // throws if already set
// after
try {
  manager.setToken(newToken);
} catch {
  // token already set — destroy and rebuild if a change is truly required
  await manager.destroy();
  manager = new WebSocketManager(options);
  manager.setToken(newToken);
}
Defensive patterns

Strategy: validation

Validate before calling

let tokenApplied = false;
function safeSetToken(manager: WebSocketManager, token: string): void {
  if (!tokenApplied) {
    manager.setToken(token);
    tokenApplied = true;
  }
}

Try / catch

try {
  manager.setToken(newToken);
} catch (e) {
  if (e instanceof Error && e.message.includes('already been set')) {
    // token is immutable; ignore or recreate the manager
  } else throw e;
}

Prevention

When it happens

Trigger: Calling manager.setToken(...) a second time on the same WebSocketManager instance, e.g. during a config reload or when reusing a cached manager instance.

Common situations: Hot-reloading configuration code that re-runs setToken(); accidentally constructing once globally but calling setToken in a per-request/per-event handler; unit tests reusing a module-level manager.

Related errors


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