remix-run/remix · error · Error

Invalid tsconfig compilerOptions for ${filePath}.\nremix/nod

Error message

Invalid tsconfig compilerOptions for ${filePath}.\nremix/node-tsx only supports string values for JSX transform options.\n${details}

What it means

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.

Source

Thrown at packages/node-tsx/src/lib/transform.ts:116

  let options: TsconfigTransformCompilerOptions = {}
  let issues: TsconfigTransformCompilerOptionsIssue[] = []

  for (let key of tsconfigTransformCompilerOptionKeys) {
    let value = compilerOptions[key]
    if (value === undefined) {
      continue
    }

    if (typeof value !== 'string') {
      issues.push({ key, value })
      continue
    }

    options[key] = value
  }

  if (issues.length > 0) {
    throw createTsconfigCompilerOptionsError(filePath, issues)
  }

  return options
}

function createTsconfigCompilerOptionsError(
  filePath: string,
  issues: TsconfigTransformCompilerOptionsIssue[],
): Error {
  let details = issues.map(formatTsconfigCompilerOptionsIssue).join('\n')
  return new Error(
    `Invalid tsconfig compilerOptions for ${filePath}.\n` +
      `remix/node-tsx only supports string values for JSX transform options.\n${details}`,
  )
}

function formatTsconfigCompilerOptionsIssue(issue: TsconfigTransformCompilerOptionsIssue): string {
  return `- compilerOptions.${issue.key}: Expected string, received ${getValueType(issue.value)}`

View on GitHub (pinned to 9696913134)

Solutions

  1. Open the tsconfig named in the message and make every JSX-related compilerOption a string
  2. Validate the tsconfig (e.g. `npx tsc --noEmit` or a JSON schema check)
  3. If an option is unused, remove it rather than leaving a non-string value

Example fix

// before (tsconfig.json)
{ "compilerOptions": { "jsxImportSource": { "precompile": true } } }
// after
{ "compilerOptions": { "jsxImportSource": "react" } }
Defensive patterns

Strategy: validation

Validate before calling

import tsconfig from './tsconfig.json' with { type: 'json' }
const JSX_KEYS = ['jsxFactory', 'jsxFragmentFactory', 'jsxImportSource']
for (const key of JSX_KEYS) {
  const value = (tsconfig.compilerOptions as Record<string, unknown>)[key]
  if (value != null && typeof value !== 'string') throw new Error(`${key} must be a string`)
}

Type guard

const hasStringJsxOptions = (opts: Record<string, unknown>): boolean =>
  ['jsxFactory', 'jsxFragmentFactory', 'jsxImportSource']
    .filter((k) => opts[k] != null)
    .every((k) => typeof opts[k] === 'string')

Prevention

When it happens

Trigger: 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.

Common situations: Hand-edited or generated tsconfig with numbers/booleans/objects in JSX options; sharing a tsconfig across tools that expect different option shapes.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/8f2e1075942081ba. Report an issue: GitHub.