{"record":{"id":"443f73b6c86e855a","repo":"jestjs/jest","slug":"jest-you-can-only-define-a-single-loader-through","errorCode":null,"errorMessage":"Jest: You can only define a single loader through docblocks, got \"${tsLoader.join(', ')}\"","messagePattern":"Jest: You can only define a single loader through docblocks, got \"(.+?)\"","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/jest-config/src/readConfigFileAndSetRootDir.ts","lineNumber":163,"sourceCode":"\nconst loadDocblockPragmasInConfig = (configPath: string): Pragmas => {\n  const docblockPragmas = parse(extract(fs.readFileSync(configPath, 'utf8')));\n  return docblockPragmas;\n};\n\nconst loadTSConfigFile = async (\n  configPath: string,\n): Promise<Config.InitialOptions> => {\n  // Get registered TypeScript compiler instance\n  const docblockPragmas = loadDocblockPragmasInConfig(configPath);\n  const tsLoader = docblockPragmas['jest-config-loader'] || 'ts-node';\n  const docblockTSLoaderOptions = docblockPragmas['jest-config-loader-options'];\n\n  if (typeof docblockTSLoaderOptions === 'string') {\n    extraTSLoaderOptions = JSON.parse(docblockTSLoaderOptions);\n  }\n  if (Array.isArray(tsLoader)) {\n    throw new TypeError(\n      `Jest: You can only define a single loader through docblocks, got \"${tsLoader.join(\n        ', ',\n      )}\"`,\n    );\n  }\n\n  const registeredCompiler = await getRegisteredCompiler(\n    tsLoader as TsLoaderModule,\n  );\n  registeredCompiler.enabled(true);\n\n  let configObject = interopRequireDefault(require(configPath)).default;\n\n  // In case the config is a function which imports more Typescript code\n  if (typeof configObject === 'function') {\n    configObject = await configObject();\n  }\n","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-config/src/readConfigFileAndSetRootDir.ts#L145-L181","documentation":"Thrown as a TypeError by loadTSConfigFile when the jest-docblock parser returns an Array for the @jest-config-loader pragma. Docblock pragmas become arrays when the same tag is declared more than once in the file header, and the loader supports only a single loader.","triggerScenarios":"Having two or more '@jest-config-loader' lines in the jest.config.ts/.cts docblock header, e.g. one declaring ts-node and another esbuild-register.","commonSituations":"Merging config snippets from different sources without deduplicating the docblock; copying examples that each carried their own loader pragma; tooling that auto-injects pragmas.","solutions":["Open the config file and remove all but one @jest-config-loader line","Choose the loader you actually want (ts-node or esbuild-register) and keep only that one","Run prettier/eslint with docblock awareness to catch duplicate pragmas in future"],"exampleFix":"/**\n * @jest-config-loader ts-node\n * @jest-config-loader esbuild-register\n */\n// before: two loaders -> error\n\n/**\n * @jest-config-loader ts-node\n */\n// after: single loader","handlingStrategy":"validation","validationCode":"import { extract, parse } from 'jest-docblock';\nimport * as fs from 'node:fs';\nconst pragmas = parse(extract(fs.readFileSync('jest.config.ts', 'utf8')));\nif (Array.isArray(pragmas['jest-config-loader'])) {\n  throw new Error('Duplicate @jest-config-loader pragma detected');\n}","typeGuard":"function hasSingleLoaderPragma(pragmas: Record<string, unknown>): boolean {\n  const v = pragmas['jest-config-loader'];\n  return v === undefined || typeof v === 'string';\n}","tryCatchPattern":null,"preventionTips":["Keep a single docblock header in the config file","Lint duplicate pragmas in a precommit hook","When merging config snippets, deduplicate docblock pragmas explicitly"],"tags":["typescript","config","docblock","loader","argument-validation"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}