{"id":"34c2a70c650f9f77","repo":"jestjs/jest","slug":"jest-failed-to-parse-the-typescript-config-file","errorCode":null,"errorMessage":"Jest: Failed to parse the TypeScript config file ${configPath}\n  ${error}","messagePattern":"Jest: Failed to parse the TypeScript config file (.+?)\n  (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-config/src/readConfigFileAndSetRootDir.ts","lineNumber":97,"sourceCode":"              '  both with the native node TypeScript support and configured TypeScript loaders.\\n' +\n              '    Errors were:\\n' +\n              `    - ${requireOrImportModuleError}\\n` +\n              `    - ${loadTSConfigFileError}`\n            );\n          }\n        }\n      } else {\n        configObject = await loadTSConfigFile(configPath);\n      }\n    } else if (isJSON) {\n      const fileContent = fs.readFileSync(configPath, 'utf8');\n      configObject = parseJson(stripJsonComments(fileContent), configPath);\n    } else {\n      configObject = await requireOrImportModule<any>(configPath);\n    }\n  } catch (error) {\n    if (isTS) {\n      throw new Error(\n        `Jest: Failed to parse the TypeScript config file ${configPath}\\n` +\n          `  ${error}`,\n      );\n    }\n\n    throw error;\n  }\n\n  if (configPath.endsWith(PACKAGE_JSON)) {\n    // Event if there's no \"jest\" property in package.json we will still use\n    // an empty object.\n    configObject = configObject.jest || {};\n  }\n\n  if (typeof configObject === 'function') {\n    configObject = await configObject();\n  }\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-config/src/readConfigFileAndSetRootDir.ts#L79-L115","documentation":"The outer catch-all in readConfigFileAndSetRootDir wraps any failure to load a TypeScript config file with the offending path and the underlying error. It commonly wraps the combined 'both native and loader failed' string thrown from the inner try, surfacing both failure reasons together. It fires only for .ts/.mts/.cts configs.","triggerScenarios":"A jest.config.ts with a syntax error, an import of a missing module from the config, invalid TypeScript that neither native Node nor ts-node can compile, or a config using ESM syntax in a CJS context with no working loader.","commonSituations":"Broken imports in the config after a refactor; ts-node not installed but config uses TS-only features incompatible with native strip-types; type errors that break compilation under stricter loader settings.","solutions":["Read the full wrapped error message - it lists both the native and loader failure reasons","Reproduce in isolation by running `node --experimental-strip-types jest.config.ts` or `ts-node jest.config.ts` directly","Install/verify the configured loader (ts-node or esbuild-register) if native compilation is insufficient","Fix the TypeScript or import error indicated in the nested message"],"exampleFix":"// before: jest.config.ts imports a non-existent preset\nimport base from './nonexistent';\nexport default {...base};\n// after\nimport base from './jest.base';\nexport default {...base};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const config = await readConfigFileAndSetRootDir(configPath);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Jest: Failed to parse the TypeScript config file')) {\n    // inspect the inner cause: missing loader vs syntax error vs missing import\n    console.error('TS config load failed:', e.message);\n  }\n  throw e;\n}","preventionTips":["Validate jest.config.ts compiles with tsc --noEmit before committing","Keep config imports minimal and relative","Pin loader versions in devDependencies"],"tags":["typescript","config","loader"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}