Skip to content
Latchkey

esbuild "Transform failed with N errors" - Fix in CI

esbuild tried to transform a file and could not. The message names the file, line, and a specific syntax error - JSX fed to a non-JSX loader, a real parse error, or a syntax the configured target rejects.

What this error means

A build using esbuild (directly, or via Vite/tsup) fails with Transform failed with N errors followed by ERROR: <file>:<line>: .... It is deterministic and points at the exact location.

esbuild
✘ [ERROR] Transform failed with 1 error:
src/components/Card.tsx:14:2: ERROR: Expected ">" but found "className"
    at failureErrorWithLog (/app/node_modules/esbuild/lib/main.js:1649:15)

Common causes

JSX handled by the wrong loader

JSX in a .ts file (instead of .tsx), or a loader: 'ts' where JSX appears, makes esbuild parse < as an operator and fail.

Genuine syntax error

A stray token, unclosed brace, or invalid construct in the source - a real error esbuild reports at the exact line/column.

Syntax newer than the target

A target set too low (e.g. es2015) can reject or fail to transform syntax the source uses.

How to fix it

Fix the loader/extension or syntax

  1. Put JSX in .tsx/.jsx, or set the esbuild loader to tsx/jsx for the file.
  2. Open the reported line and correct the actual syntax error.
  3. Confirm the file also type-checks with tsc --noEmit.

Set an appropriate target/loader in config

esbuild config
// esbuild config
{ loader: { '.ts': 'tsx' }, jsx: 'automatic', target: 'es2020' }

How to prevent it

  • Keep JSX in .tsx/.jsx so esbuild selects the JSX loader.
  • Set a target that matches the syntax your source uses.
  • Type-check in CI so syntax errors surface before the transform.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →