{"record":{"id":"b5ebd13e0c08840e","repo":"discordjs/discord.js","slug":"cannot-instantiate-workercontextfetchingstrategy-o","errorCode":null,"errorMessage":"Cannot instantiate WorkerContextFetchingStrategy on the main thread","messagePattern":"Cannot instantiate WorkerContextFetchingStrategy on the main thread","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ws/src/strategies/context/WorkerContextFetchingStrategy.ts","lineNumber":22,"sourceCode":"import {\n\tWorkerReceivePayloadOp,\n\tWorkerSendPayloadOp,\n\ttype WorkerReceivePayload,\n\ttype WorkerSendPayload,\n} from '../sharding/WorkerShardingStrategy.js';\nimport type { FetchingStrategyOptions, IContextFetchingStrategy } from './IContextFetchingStrategy.js';\n\nexport class WorkerContextFetchingStrategy implements IContextFetchingStrategy {\n\tprivate readonly sessionPromises = new Collection<number, (session: SessionInfo | null) => void>();\n\n\tprivate readonly waitForIdentifyPromises = new Collection<\n\t\tnumber,\n\t\t{ reject(error: unknown): void; resolve(): void; signal: AbortSignal }\n\t>();\n\n\tpublic constructor(public readonly options: FetchingStrategyOptions) {\n\t\tif (isMainThread) {\n\t\t\tthrow new Error('Cannot instantiate WorkerContextFetchingStrategy on the main thread');\n\t\t}\n\n\t\tparentPort!.on('message', (payload: WorkerSendPayload) => {\n\t\t\tif (payload.op === WorkerSendPayloadOp.SessionInfoResponse) {\n\t\t\t\tthis.sessionPromises.get(payload.nonce)?.(payload.session);\n\t\t\t\tthis.sessionPromises.delete(payload.nonce);\n\t\t\t}\n\n\t\t\tif (payload.op === WorkerSendPayloadOp.ShardIdentifyResponse) {\n\t\t\t\tconst promise = this.waitForIdentifyPromises.get(payload.nonce);\n\t\t\t\tif (payload.ok) {\n\t\t\t\t\tpromise?.resolve();\n\t\t\t\t} else {\n\t\t\t\t\t// We need to make sure we reject with an abort error\n\t\t\t\t\tpromise?.reject(promise.signal.reason);\n\t\t\t\t}\n\n\t\t\t\tthis.waitForIdentifyPromises.delete(payload.nonce);","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/ws/src/strategies/context/WorkerContextFetchingStrategy.ts#L4-L40","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (main entry file)\nimport { WorkerContextFetchingStrategy } from '@discordjs/ws';\nconst strategy = new WorkerContextFetchingStrategy(options);\n// after\nimport { MainContextFetchingStrategy } from '@discordjs/ws';\nconst strategy = new MainContextFetchingStrategy(options);\n// or inside worker code only:\n// new WorkerContextFetchingStrategy(options) where !isMainThread","handlingStrategy":"validation","validationCode":"import { isMainThread } from 'node:worker_threads';\nimport { WorkerContextFetchingStrategy, MainContextFetchingStrategy } from '@discordjs/ws';\nfunction createStrategy(options) {\n  return isMainThread\n    ? new MainContextFetchingStrategy(options)\n    : new WorkerContextFetchingStrategy(options);\n}","typeGuard":"const isWorkerThread = () => !isMainThread;\nif (isWorkerThread()) { /* safe to construct WorkerContextFetchingStrategy */ }","tryCatchPattern":"try {\n  strategy = new WorkerContextFetchingStrategy(options);\n} catch (err) {\n  if (err instanceof Error && /main thread/.test(err.message)) {\n    strategy = new MainContextFetchingStrategy(options);\n  } else throw err;\n}","preventionTips":["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."],"tags":["worker-threads","nodejs","misconfiguration","threading"],"backgroundTag":"wrong-thread-context","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}