jestjs/jest · error · TypeError
Jest: You can only define a single loader through docblocks,
Error message
Jest: You can only define a single loader through docblocks, got "${tsLoader.join(', ')}" What it means
When loading a TS config via a loader, Jest reads the `@jest-config-loader` pragma from the docblock at the top of the config file. The pragma must name exactly one loader ('ts-node' or 'esbuild-register'). If the docblock contains the pragma twice, jest-docblock returns an array, and this TypeError is thrown.
Source
Thrown at packages/jest-config/src/readConfigFileAndSetRootDir.ts:162
const loadDocblockPragmasInConfig = (configPath: string): Pragmas => {
const docblockPragmas = parse(extract(fs.readFileSync(configPath, 'utf8')));
return docblockPragmas;
};
const loadTSConfigFile = async (
configPath: string,
): Promise<Config.InitialOptions> => {
// Get registered TypeScript compiler instance
const docblockPragmas = loadDocblockPragmasInConfig(configPath);
const tsLoader = docblockPragmas['jest-config-loader'] || 'ts-node';
const docblockTSLoaderOptions = docblockPragmas['jest-config-loader-options'];
if (typeof docblockTSLoaderOptions === 'string') {
extraTSLoaderOptions = JSON.parse(docblockTSLoaderOptions);
}
if (Array.isArray(tsLoader)) {
throw new TypeError(
`Jest: You can only define a single loader through docblocks, got "${tsLoader.join(
', ',
)}"`,
);
}
const registeredCompiler = await getRegisteredCompiler(
tsLoader as TsLoaderModule,
);
registeredCompiler.enabled(true);
let configObject = interopRequireDefault(require(configPath)).default;
// In case the config is a function which imports more Typescript code
if (typeof configObject === 'function') {
configObject = await configObject();
}
View on GitHub (pinned to f49721c78e)
Solutions
- Keep only one @jest-config-loader line in the docblock
- Remove the docblock entirely to use the default 'ts-node' loader
Example fix
/** * @jest-config-loader ts-node * @jest-config-loader esbuild-register */ // becomes /** * @jest-config-loader ts-node */
Defensive patterns
Strategy: validation
Validate before calling
import {parse, extract} from 'jest-docblock';
import * as fs from 'node:fs';
const pragmas = parse(extract(fs.readFileSync('jest.config.ts', 'utf8')));
const loader = pragmas['jest-config-loader'];
if (Array.isArray(loader)) {
throw new Error('Multiple @jest-config-loader pragmas detected');
} Prevention
- Lint docblock pragmas to forbid duplicates
- Maintain a single source config docblock template
When it happens
Trigger: Writing `@jest-config-loader ts-node` and `@jest-config-loader esbuild-register` in the same docblock header of jest.config.ts.
Common situations: Copy-pasting a docblock from two sources; merging config snippets without deduplicating pragmas.
Related errors
- Jest: '${loader}' is not a valid TypeScript configuration lo
- Jest: Failed to parse the TypeScript config file ${configPat
- Jest: '${loader}' is required for the TypeScript configurati
- jest.config.mts requires native TypeScript support. Ensure y
- ${moduleName} file must export a function at ${modulePath}
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/443f73b6c86e855a.json.
Report an issue: GitHub.