gohugoio/hugo · error

esbuild: entry point output not found

Error message

esbuild: entry point output not found

What it means

After running esbuild, Hugo walks the output files, publishing source maps and file-loader artifacts and capturing the main bundle (the stdin entry point output). If no output file matches the expected stdin entry name, mainOutput stays nil and Hugo reports that esbuild produced no entry-point output. This is a guard against silently publishing an empty bundle and usually indicates esbuild produced nothing or only artifacts.

Source

Thrown at resources/resource_transformers/js/build.go:110

		basePath := path.Base(filepath.ToSlash(file.Path))
		if strings.HasSuffix(basePath, ".map") {
			if hasSourceMap {
				if err = transformCtx.PublishSourceMap(file.Contents); err != nil {
					return result, err
				}
			}
		} else if isStdinEntryOutput(basePath) {
			mainOutput = file.Contents
		} else {
			// File-loader artifact; publish directly.
			if err = publishFileLoaderArtifact(pathSpec, opts.PublicPath, outDir, basePath, file.Contents, transformCtx); err != nil {
				return result, err
			}
		}
	}

	if mainOutput == nil {
		return result, fmt.Errorf("esbuild: entry point output not found")
	}

	if hasLinkedSourceMap {
		symPath := path.Base(transformCtx.OutPath) + ".map"
		if opts.IsCSS {
			re := regexp.MustCompile(`/\*# sourceMappingURL=.*\n?`)
			mainOutput = re.ReplaceAll(mainOutput, []byte("/*# sourceMappingURL="+symPath+" */\n"))
		} else {
			re := regexp.MustCompile(`//# sourceMappingURL=.*\n?`)
			mainOutput = re.ReplaceAll(mainOutput, []byte("//# sourceMappingURL="+symPath+"\n"))
		}
	}

	if _, err = transformCtx.To.Write(mainOutput); err != nil {
		return result, err
	}

	return result, nil

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Simplify the js.Build options to defaults and re-add options one at a time to find the one breaking entry output naming.
  2. Verify the entry script actually produces output (not an empty file / all-side-effect-free tree-shaken module).
  3. Upgrade Hugo — entry-output detection has changed across versions; a mismatch can be a fixed bug.
  4. Run hugo with --logLevel debug to see the transform inputs, and report a minimal reproduction if it persists.
Defensive patterns

Strategy: validation

Validate before calling

{{ $entry := resources.Get "js/main.js" }}
{{ if not $entry }}{{ errorf "missing js entry point assets/js/main.js" }}{{ end }}
{{ $built := $entry | js.Build (dict "target" "es2018") }}

Try / catch

{{ with try (js.Build $entry $opts) }}{{ with .Err }}{{ errorf "js.Build failed: %s" . }}{{ end }}{{ end }}

Prevention

When it happens

Trigger: js.Build/js.Batch runs where esbuild's OutputFiles contain no file recognized by isStdinEntryOutput — e.g. every output is a .map or a file-loader asset, or an esbuild option combination (unusual entryNames/splitting/plugin behavior) renamed the entry output so it no longer matches the stdin entry naming.

Common situations: Custom esbuild params (via the params/defines/plugins options) that alter output naming; edge cases after Hugo or esbuild version upgrades changing output naming conventions; sourceMap-only outputs when the entry compiles to nothing.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/3967f9ff58938844.json. Report an issue: GitHub ↗.