Skip to content
Latchkey

esbuild "Transform failed with N errors" (syntax) in CI

esbuild hit a syntax construct it was not told to parse - JSX in a .js file, TypeScript types without the ts loader, or decorators - and aborted the transform.

What this error means

The build fails with "Transform failed with 1 error" and a pointer at JSX, a type annotation, or a decorator. It compiles under your app toolchain because that one applies the right loader.

node
> Transform failed with 1 error:
src/App.js:12:9: ERROR: Expected ">" but found "className"

  12 |   return <div className="x" />;
     |               ^

Common causes

The loader does not match the syntax

A .js file contains JSX, or a .ts file uses decorators, but esbuild was given the plain js loader or default options.

Target excludes a needed feature

An aggressive target disabled parsing of a syntax that the source still uses.

How to fix it

Set the correct loader for the extension

Tell esbuild to treat the file as jsx/ts/tsx so it parses the syntax in use.

build script
await esbuild.build({
  loader: { '.js': 'jsx' },
  jsx: 'automatic',
});

Enable TypeScript and decorator support

Use the ts/tsx loader and a tsconfig that turns on the features your code relies on.

  1. Rename JSX-containing files to .jsx/.tsx, or set the jsx loader for .js.
  2. Point esbuild at your tsconfig so experimentalDecorators is honored.
  3. Re-run the build on a clean checkout.

How to prevent it

  • Use file extensions that match their syntax (.jsx, .tsx).
  • Pass a tsconfig to esbuild so feature flags are consistent.
  • Keep the esbuild target in line with the syntax your source uses.

Related guides

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