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, nilView on GitHub ↗ (pinned to 8a468df065)
Solutions
- Simplify the js.Build options to defaults and re-add options one at a time to find the one breaking entry output naming.
- Verify the entry script actually produces output (not an empty file / all-side-effect-free tree-shaken module).
- Upgrade Hugo — entry-output detection has changed across versions; a mismatch can be a fixed bug.
- 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
- Verify the entry file exists in assets/ and has a supported extension (.js/.ts/.jsx/.tsx)
- Check esbuild `format`/`target` options are valid; invalid configs can yield no output
- Run `hugo --logLevel debug` to see esbuild diagnostics before the missing-output error
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
- no Resource provided in transformation
- must not provide more arguments than resource object and opt
- resources in Concat must be of the same Media Type, got %q a
- failed to parse Resource %q as Template:: %w
- inject: absolute paths not supported, must be relative to /a
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/3967f9ff58938844.json.
Report an issue: GitHub ↗.