gohugoio/hugo · error

{}

Error message

{}

What it means

Returned by the esbuild Build wrapper in internal/js/esbuild/build.go:109 when esbuild reports an error message (api.Message) whose Location is nil. Because there is no source position, Hugo surfaces the raw msg.Text rather than a file-position error. The {} placeholder denotes the message is whatever esbuild produced.

Source

Thrown at internal/js/esbuild/build.go:109

			if m == nil {
				return api.BuildResult{}, fmt.Errorf("inject: file %q not found", ext)
			}

			opts.Inject[i] = m.Filename

		}

		opts.compiled.Inject = opts.Inject

	}

	result := api.Build(opts.compiled)

	if len(result.Errors) > 0 {
		createErr := func(msg api.Message) error {
			if msg.Location == nil {
				return errors.New(msg.Text)
			}
			var (
				contentr     hugio.ReadSeekCloser
				errorMessage string
				loc          = msg.Location
				errorPath    = loc.File
				err          error
			)

			var resolvedError *ErrorMessageResolved

			if opts.ErrorMessageResolveFunc != nil {
				resolvedError = opts.ErrorMessageResolveFunc(msg)
			}

			if resolvedError == nil {
				if errorPath == stdinImporter {
					errorPath = opts.StdinSourcePath

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Read the full error text (Hugo prints msg.Text) for the esbuild-specific cause.
  2. Validate the options map passed to js.Build / opts.validate() against esbuild's supported options.
  3. Simplify the build (disable minify, sourceMap, or splitting) to isolate which option triggers the message.
  4. Check that the entry source is non-empty and reachable before bundling.

Example fix

// before
{{ $js = resources.Get "main.js" | js.Build (dict "sourceMap" "invalid") }}
// after
{{ $js = resources.Get "main.js" | js.Build (dict "sourceMap" "inline") }}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate options before building where possible.
// Hugo's opts.validate() checks struct fields; confirm dict keys are valid esbuild options.

Try / catch

// Wrap js.Build so build failures don't abort rendering if optional.
{{ with resources.Get "main.js" }}
  {{ with js.Build . | try }}{{ . }}{{ else }}{{ warnf "js.Build failed: %s" . }}{{ end }}
{{ end }}

Prevention

When it happens

Trigger: Calling js.Build / css.Build (or BuildClient.Build in Go) and esbuild emits a non-located error: an invalid build option, a top-level resolution failure with no file context, or an internal esbuild error. These are errors esbuild itself cannot tie to a source line.

Common situations: Passing unsupported options to js.Build (e.g. an unknown target/sourceMap value), a bundler-level failure before any file is parsed, or an esbuild version mismatch producing a generic error string.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/b8b2678c296a68eb. Report an issue: GitHub.