serverless/serverless · error · ServerlessError

ESBULD_BUILD_ERROR

ESBULD_BUILD_ERROR

Error message

${err.message}

What it means

Generic wrapper for esbuild's own build failures: when the build step throws and the error is not already a ServerlessError raised deliberately by the plugin (output collision, outExtension mismatch, etc.), it is re-wrapped with code ESBULD_BUILD_ERROR keeping the original message. Read err.message — it is esbuild's underlying diagnostic.

Source

Thrown at packages/serverless/lib/plugins/esbuild/index.js:1072

      }

      try {
        await this._buildProject(
          functionsToBuild,
          handlerPropertyName,
          buildProperties,
        )
      } catch (err) {
        if (this.serverless.devmodeEnabled === true) {
          return
        }
        // Errors this path raises deliberately (an output collision, an
        // unusable `outExtension`) already say what to do about them; only
        // esbuild's own failures need wrapping.
        if (err instanceof ServerlessError) {
          throw err
        }
        throw new ServerlessError(err.message, 'ESBULD_BUILD_ERROR')
      }

      if (handlerPropertyName !== 'originalHandler') {
        this._assertAllHandlersBuilt(functionsToBuild, handlerPropertyName)
      }

      return
    }

    const outputExtension = this._outputExtension(buildProperties)

    // Multiple functions can share a single handler file (e.g. one module
    // exporting several handlers). Building each function separately would
    // spawn concurrent esbuild.build() calls writing to the same outfile,
    // racing on truncate+write and corrupting the output (#13716). Instead we
    // group functions by their resolved absolute entry path and build each
    // unique file once, applying the per-function side effects to every alias
    // in the group afterwards.

View on GitHub (pinned to ba6ba66c01)

Solutions

  1. Read err.message for esbuild's actual diagnostic and fix the source/import it names
  2. Run esbuild or tsc directly on the file to reproduce the error faster
  3. Verify tsconfig and build.esbuild options (target, loaders, plugins) are valid
  4. If a plugin you added throws, fix or remove that plugin

Example fix

// before
import { foo } from './nonexistent'
// after
import { foo } from './utils'
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check: compile the entry points with esbuild directly to surface diagnostics early
import { build } from 'esbuild'
await build({ entryPoints: ['src/handler.ts'], bundle: true, write: false, logLevel: 'silent' })

Try / catch

try {
  await deploy()
} catch (e) {
  if (e.code === 'ESBULD_BUILD_ERROR') {
    // e.message is esbuild's own diagnostic; surface it verbatim
    console.error('esbuild failed:', e.message)
  }
  throw e
}

Prevention

When it happens

Trigger: Any esbuild compilation failure during _buildProject: syntax errors, unresolved imports, invalid loader/plugin errors, tsconfig problems — anything esbuild itself rejects.

Common situations: TypeScript type/syntax errors, importing a missing module, a bad tsconfig path, unsupported syntax for the target runtime.

Related errors


AI-assisted analysis of serverless/serverless@ba6ba66c01 (2026-09-13). Data as JSON: /api/errors/e3b455f1bf146d0f. Report an issue: GitHub.