gohugoio/hugo · error
only esm format is currently supported
Error message
only esm format is currently supported
What it means
Hugo's JS batcher only supports the ES module output format. If externalOptions.Format (compiled from the options map) is set to anything other than "esm" — e.g. "iife", "cjs", "umd" — build() rejects it at batch.go:523-528. An empty format is auto-defaulted to "esm", so the error only fires when a non-esm value is explicitly provided.
Solutions
- Set Format to "esm" (the default and only supported value).
- Omit Format entirely so it defaults to "esm".
- If you need IIFE/UMD output, use Hugo's js.Build resource transform with compatible options instead of the batcher.
Example fix
// before
opts := map[string]any{"format": "iife"}
// after
opts := map[string]any{"format": "esm"}
// or simply omit "format" Defensive patterns
Strategy: validation
Validate before calling
func validateBatchFormat(opts map[string]any) error {
if f, ok := opts["format"].(string); ok && f != "" && f != "esm" {
return fmt.Errorf("only esm format is currently supported (got %q)", f)
}
return nil
} Type guard
func isSupportedFormat(f string) bool { return f == "" || f == "esm" } Prevention
- Omit 'format' so it defaults to "esm", or set it explicitly to "esm".
- Avoid porting IIFE/UMD/CJS esbuild configs into the batcher.
- Validate options maps before passing them to SetOptions/Build.
When it happens
Trigger: Passing options with Format set to "iife", "cjs", or any non-esm string to the JS batch/bundler options (e.g. via js.Build options or the batch config options map).
Common situations: Porting a non-Hugo esbuild config that used IIFE/UMD for legacy browsers; setting target/format options intended for a different bundler; copy-pasting an esbuild snippet with format: 'iife'.
Related errors
- failed to build JS batch
- failed to build JS batch
- id must be set
- id must not contain backslashes
- id must not contain forward slashes
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/4ff9a5e738cd9740.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/esbuild/batch.go:527
}
state.importerImportContext.Set(s, importContext{
name: s,
resourceGetter: nil,
dm: g.dependencyManager,
})
addResource(g.id, s, r, true)
}
mediaTypes := b.client.d.ResourceSpec.MediaTypes()
externalOptions := b.configOptions.Compiled().Options
if externalOptions.Format == "" {
externalOptions.Format = "esm"
}
if externalOptions.Format != "esm" {
return nil, fmt.Errorf("only esm format is currently supported")
}
jsOpts := Options{
ExternalOptions: externalOptions,
InternalOptions: InternalOptions{
DependencyManager: b.dependencyManager,
Splitting: true,
ImportOnResolveFunc: func(imp string, args api.OnResolveArgs) string {
var importContextPath string
if args.Kind == api.ResolveEntryPoint {
importContextPath = args.Path
} else {
importContextPath = args.Importer
}
importContext, importContextFound := state.importerImportContext.Get(importContextPath)
// We want to track the dependencies closest to where they're used.
dm := b.dependencyManagerView on GitHub (pinned to 52c9bd7908)