{"record":{"id":"8f2e1075942081ba","repo":"remix-run/remix","slug":"invalid-tsconfig-compileroptions-for-filepath","errorCode":null,"errorMessage":"Invalid tsconfig compilerOptions for ${filePath}.\\nremix/node-tsx only supports string values for JSX transform options.\\n${details}","messagePattern":"Invalid tsconfig compilerOptions for (.+?)\\.\\\\nremix/node-tsx only supports string values for JSX transform options\\.\\\\n(.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/node-tsx/src/lib/transform.ts","lineNumber":116,"sourceCode":"  let options: TsconfigTransformCompilerOptions = {}\n  let issues: TsconfigTransformCompilerOptionsIssue[] = []\n\n  for (let key of tsconfigTransformCompilerOptionKeys) {\n    let value = compilerOptions[key]\n    if (value === undefined) {\n      continue\n    }\n\n    if (typeof value !== 'string') {\n      issues.push({ key, value })\n      continue\n    }\n\n    options[key] = value\n  }\n\n  if (issues.length > 0) {\n    throw createTsconfigCompilerOptionsError(filePath, issues)\n  }\n\n  return options\n}\n\nfunction createTsconfigCompilerOptionsError(\n  filePath: string,\n  issues: TsconfigTransformCompilerOptionsIssue[],\n): Error {\n  let details = issues.map(formatTsconfigCompilerOptionsIssue).join('\\n')\n  return new Error(\n    `Invalid tsconfig compilerOptions for ${filePath}.\\n` +\n      `remix/node-tsx only supports string values for JSX transform options.\\n${details}`,\n  )\n}\n\nfunction formatTsconfigCompilerOptionsIssue(issue: TsconfigTransformCompilerOptionsIssue): string {\n  return `- compilerOptions.${issue.key}: Expected string, received ${getValueType(issue.value)}`","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/node-tsx/src/lib/transform.ts#L98-L134","documentation":"When node-tsx derives JSX transform options from tsconfig compilerOptions, it only accepts string values. Non-string values (e.g. numeric `jsxImportSource`-adjacent options, enums, or objects) are collected as issues, and parseTsconfigTransformCompilerOptions throws with the file path, an explanation, and the issue details.","triggerScenarios":"A tsconfig.json whose JSX-related compilerOptions (such as `jsxFactory`, `jsxFragmentFactory`, `jsxImportSource`) are non-string values, read while node-tsx loads a module in that project.","commonSituations":"Hand-edited or generated tsconfig with numbers/booleans/objects in JSX options; sharing a tsconfig across tools that expect different option shapes.","solutions":["Open the tsconfig named in the message and make every JSX-related compilerOption a string","Validate the tsconfig (e.g. `npx tsc --noEmit` or a JSON schema check)","If an option is unused, remove it rather than leaving a non-string value"],"exampleFix":"// before (tsconfig.json)\n{ \"compilerOptions\": { \"jsxImportSource\": { \"precompile\": true } } }\n// after\n{ \"compilerOptions\": { \"jsxImportSource\": \"react\" } }","handlingStrategy":"validation","validationCode":"import tsconfig from './tsconfig.json' with { type: 'json' }\nconst JSX_KEYS = ['jsxFactory', 'jsxFragmentFactory', 'jsxImportSource']\nfor (const key of JSX_KEYS) {\n  const value = (tsconfig.compilerOptions as Record<string, unknown>)[key]\n  if (value != null && typeof value !== 'string') throw new Error(`${key} must be a string`)\n}","typeGuard":"const hasStringJsxOptions = (opts: Record<string, unknown>): boolean =>\n  ['jsxFactory', 'jsxFragmentFactory', 'jsxImportSource']\n    .filter((k) => opts[k] != null)\n    .every((k) => typeof opts[k] === 'string')","tryCatchPattern":null,"preventionTips":["Validate tsconfig against the TS JSON schema in CI","Keep JSX compiler options as plain strings"],"tags":["typescript","tsconfig","jsx"],"backgroundTag":"tsconfig-invalid-option","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}