discordjs/discord.js · error · Error
Cannot instantiate WorkerContextFetchingStrategy on the main
Error message
Cannot instantiate WorkerContextFetchingStrategy on the main thread
What it means
WorkerContextFetchingStrategy is the WebSocket manager's fetching strategy that runs inside a worker_threads child worker and forwards session-info requests to the main thread over parentPort messaging. Its constructor checks isMainThread and throws immediately if instantiated on the main thread, because on the main thread there is no parentPort to communicate with and the MainContextFetchingStrategy should be used instead. The library offers both strategies and expects you to pick the correct one per environment.
Source
Thrown at packages/ws/src/strategies/context/WorkerContextFetchingStrategy.ts:22
import {
WorkerReceivePayloadOp,
WorkerSendPayloadOp,
type WorkerReceivePayload,
type WorkerSendPayload,
} from '../sharding/WorkerShardingStrategy.js';
import type { FetchingStrategyOptions, IContextFetchingStrategy } from './IContextFetchingStrategy.js';
export class WorkerContextFetchingStrategy implements IContextFetchingStrategy {
private readonly sessionPromises = new Collection<number, (session: SessionInfo | null) => void>();
private readonly waitForIdentifyPromises = new Collection<
number,
{ reject(error: unknown): void; resolve(): void; signal: AbortSignal }
>();
public constructor(public readonly options: FetchingStrategyOptions) {
if (isMainThread) {
throw new Error('Cannot instantiate WorkerContextFetchingStrategy on the main thread');
}
parentPort!.on('message', (payload: WorkerSendPayload) => {
if (payload.op === WorkerSendPayloadOp.SessionInfoResponse) {
this.sessionPromises.get(payload.nonce)?.(payload.session);
this.sessionPromises.delete(payload.nonce);
}
if (payload.op === WorkerSendPayloadOp.ShardIdentifyResponse) {
const promise = this.waitForIdentifyPromises.get(payload.nonce);
if (payload.ok) {
promise?.resolve();
} else {
// We need to make sure we reject with an abort error
promise?.reject(promise.signal.reason);
}
this.waitForIdentifyPromises.delete(payload.nonce);View on GitHub (pinned to a81ed8a306)
Solutions
- On the main thread use MainContextFetchingStrategy (or let createDefaultStrategy/fromSimpleShardingStrategy pick it) instead of WorkerContextFetchingStrategy.
- If you intend worker-based strategies, only construct WorkerContextFetchingStrategy inside code executed by a worker (via WorkerBootstrapper / worker_threads worker data).
- Use the library's provided strategy factories (e.g. createDefaultStrategy) rather than instantiating strategies manually so thread context is handled for you.
Example fix
// before (main entry file)
import { WorkerContextFetchingStrategy } from '@discordjs/ws';
const strategy = new WorkerContextFetchingStrategy(options);
// after
import { MainContextFetchingStrategy } from '@discordjs/ws';
const strategy = new MainContextFetchingStrategy(options);
// or inside worker code only:
// new WorkerContextFetchingStrategy(options) where !isMainThread Defensive patterns
Strategy: validation
Validate before calling
import { isMainThread } from 'node:worker_threads';
import { WorkerContextFetchingStrategy, MainContextFetchingStrategy } from '@discordjs/ws';
function createStrategy(options) {
return isMainThread
? new MainContextFetchingStrategy(options)
: new WorkerContextFetchingStrategy(options);
} Type guard
const isWorkerThread = () => !isMainThread;
if (isWorkerThread()) { /* safe to construct WorkerContextFetchingStrategy */ } Try / catch
try {
strategy = new WorkerContextFetchingStrategy(options);
} catch (err) {
if (err instanceof Error && /main thread/.test(err.message)) {
strategy = new MainContextFetchingStrategy(options);
} else throw err;
} Prevention
- Use createDefaultStrategy/fromSimpleShardingStrategy factories instead of constructing strategies by hand.
- Never import strategy classes into your main entry file when using worker-based sharding.
- Keep worker-only code in a separate file passed via the workerPath/worker strategy option.
When it happens
Trigger: Calling new WorkerContextFetchingStrategy(options) in code executing on the main thread (isMainThread === true), e.g. passing it to WebSocketManager's retrieveSessionInfoStrategy/fetchGatewayInfoStrategy options from an entry script instead of from within the worker bootstrap.
Common situations: Misconfiguring the defaultShardingStrategy/strategy options so the manager builds a worker strategy in the main process; custom setup code copied from worker examples into the main entry file; running a script directly that was intended to be bootstrapped by WorkerBootstrapper.
Related errors
- Expected WorkerBootstrap to not be used within the main thre
- ShardingWorkerExists
- No worker found for shard ${shardId}
- Shard ${shardId} does not exist
- WebSocketShard: Compression is set to native zlib but node:z
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/b5ebd13e0c08840e.
Report an issue: GitHub.