gohugoio/hugo · error
only esm format is currently supported
Error message
only esm format is currently supported
What it means
`js.Batch` relies on esbuild code splitting (`Splitting: true`), which esbuild only supports for ESM output. Hugo defaults the batch format to "esm" when unset, but if the batch config explicitly sets any other format it refuses to build with this error.
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 8a468df065)
Solutions
- Set the batch format to "esm" or simply omit the format option — esm is the default and the only supported value.
- Load the output with `<script type="module">` in your templates.
- If you truly need IIFE/CJS output, use plain `js.Build` instead of `js.Batch` (losing code splitting).
Example fix
{{/* before */}}
{{ .SetOptions (dict "format" "iife") }}
{{/* after */}}
{{ .SetOptions (dict "format" "esm") }} Defensive patterns
Strategy: validation
Validate before calling
// In config for a js.Batch group:
if opts.Format != "" && opts.Format != "esm" {
return errors.New("js.Batch only supports format \"esm\"; remove the format option or set it to esm")
} Prevention
- Don't set format at all in js.Batch config — esm is the only supported value and the default.
- If you need iife/cjs output, use js.Build for that script instead of putting it in a batch.
- Audit shared option dicts reused between js.Build and js.Batch; options valid for one aren't always valid for the other.
When it happens
Trigger: Setting `format` to "iife" or "cjs" in a batch's config options (`{{ with .Config }}{{ .SetOptions (dict "format" "iife") }}{{ end }}`) and then building the batch.
Common situations: Reusing js.Build option dicts (where iife is the default and valid) for a js.Batch config; trying to support legacy browsers without module support via IIFE output; assuming batch supports the same formats as js.Build.
Related errors
- inject: absolute paths not supported, must be relative to /a
- invalid engine version: %q
- unsupported target: %v
- invalid loader: %q
- unsupported script output format: %q
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/4ff9a5e738cd9740.json.
Report an issue: GitHub ↗.