gohugoio/hugo · error
esbuild: entry point output not found
Error message
esbuild: entry point output not found
What it means
Returned by the JS/esbuild transformer when, after iterating esbuild's OutputFiles, none matched isStdinEntryOutput (i.e. no file whose base name starts with 'stdin.'). Hugo runs esbuild in stdin mode for resources fetched via resources.Get, and expects esbuild to emit a stdin.js (or stdin.css) output as the main entry artifact; its absence means esbuild produced no recognizable entry-point output.
Solutions
- Upgrade the embedded/extended Hugo build to pick up a compatible esbuild version.
- Check that the source resource is non-empty and is actually JS/TS that esbuild can compile.
- Avoid overriding 'targetPath' or output options in a way that suppresses the stdin.* entry output; if reproducing, file a Hugo issue with the resource and options map.
Example fix
// before
{{ $js := resources.Get "js/empty.js" | js.Build }} // empty source
// after
{{ $js := resources.Get "js/main.js" | js.Build }} // non-empty entry Defensive patterns
Strategy: validation
Validate before calling
// Ensure the source resource is non-empty JS before js.Build.
if r == nil { return errors.New("nil resource for js.Build") }
rc, err := r.ReadSeekCloser()
if err != nil { return err }
stat, _ := rc.(interface{ Size() int64 }); if stat != nil && stat.Size() == 0 {
return errors.New("empty source for js.Build")
} Prevention
- Keep Hugo updated to a version compatible with your esbuild needs.
- Don't override output/targetPath options that suppress the stdin.* entry file.
- File a Hugo issue with a minimal reproducer if it persists on valid non-empty JS.
When it happens
Trigger: Calling js.Build on a resource and esbuild returns output files that are all sourcemaps or file-loader artifacts with no stdin.* entry file. Can happen with a misconfigured entrypoint, an esbuild version that names the stdin output differently, or an empty/zero-length source.
Common situations: A regression or version skew in esbuild changing how stdin-mode output is named; passing an options map that overrides output paths; an empty input resource (e.g. resources.Get returned an empty file) producing no JS output.
Related errors
- babel config not found
- could not find in the import context
- {}
- Error parsing JSON line\n
- Error parsing JSON line\n
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/3967f9ff58938844.
Report an issue: GitHub.
Appendix: source
Thrown at resources/resource_transformers/js/build.go:138
}
artifacts = append(artifacts, newArtifact(pathSpec.GetBasePath(false)+paths.PathEscape(paths.AddLeadingSlash(transformCtx.OutPath+".map")), basePath))
}
} 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
}
artifacts = append(artifacts, newArtifact(fileLoaderRelPermalink(basePath), basePath))
}
}
sort.Slice(artifacts, func(i, j int) bool { return artifacts[i].RelPermalink() < artifacts[j].RelPermalink() })
transformCtx.Data["Artifacts"] = artifacts
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 52c9bd7908)