gohugoio/hugo · error
binary %q is not a Node.js script
Error message
binary %q is not a Node.js script
What it means
Returned in common/hexec/exec.go:217 when Hugo resolves a command expected to be a Node.js tool (e.g. from node_modules/.bin or PATH) but resolveNodeBin cannot extract an underlying JavaScript entry script from the resolved binary. Hugo runs such tools as 'node <script> <args>' (optionally with Node permission flags), so a resolved file that isn't a Node wrapper/script cannot be executed through this path.
Source
Thrown at common/hexec/exec.go:217
resolvedBin = p
loc = binaryLocationNodeModules
} else if p, err := exec.LookPath(name); err == nil {
resolvedBin = p
loc = binaryLocationPath
} else {
return nil, &NotFoundError{name: name, method: "in PATH"}
}
scriptPath := resolveNodeBin(resolvedBin)
e.infol.WithFields(logg.Fields{
logg.Field{Name: "location", Value: loc},
logg.Field{Name: "bin", Value: resolvedBin},
logg.Field{Name: "script", Value: scriptPath},
}).Logf("resolve %q", name)
if scriptPath == "" {
return nil, fmt.Errorf("binary %q is not a Node.js script", name)
}
return func(arg2 ...any) (Runner, error) {
return e.newNode(name, scriptPath, arg2...)
}, nil
})
if err != nil {
return nil, err
}
return newRunner(arg...)
}
// newNode runs a Node.js script via "node [--permission <flags>] <scriptPath> <args>".
func (e *Exec) newNode(name, scriptPath string, arg ...any) (Runner, error) {
var allArgs []any
for _, pa := range e.nodePermissionArgs(name, scriptPath) {
allArgs = append(allArgs, pa)View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Reinstall the tool so a standard Node bin shim exists: delete node_modules and run 'npm install' (or your package manager's equivalent) in the project root.
- Verify what Hugo resolved: check node_modules/.bin/<name> and confirm it points at a .js entry (head the file / readlink).
- Ensure a native binary of the same name earlier in PATH isn't shadowing the Node package's executable.
- Try installing the tool with npm instead of pnpm/yarn if exotic shims are the cause.
Example fix
# before: broken/foreign shim in node_modules/.bin rm -rf node_modules # after: clean install restores standard Node shims npm install hugo
Defensive patterns
Strategy: validation
Validate before calling
# Verify the binary on PATH is actually a Node script (e.g. postcss, babel) head -1 "$(command -v postcss)" | grep -q 'node' || echo 'postcss is not a Node.js script'
Prevention
- Install JS tooling (postcss-cli, babel) locally via npm so Hugo resolves the Node script in node_modules/.bin, not a native binary with the same name
- Avoid shadowing tool names with unrelated native executables earlier on PATH
- After changing PATH or reinstalling tools, run a clean build to confirm resolution
When it happens
Trigger: Executing a Node-routed external command (such as PostCSS, TailwindCSS, or Babel via css.PostCSS / js build pipelines) where the file found in node_modules/.bin or PATH is not a recognizable Node.js launcher script — e.g. a native binary, a shell wrapper Hugo can't parse, or a broken symlink target.
Common situations: npm/pnpm/yarn installs that create non-standard .bin shims (pnpm shell shims on some platforms), a same-named native binary shadowing the Node tool on PATH, corrupted or partially installed node_modules, or Windows .cmd/.ps1 shim variations Hugo's resolver doesn't map to a script.
Related errors
- failed to resolve output path %q: %w
- module workspace %q does not exist. Check your module.worksp
- must not provide more arguments than resource object and opt
- postcss config %q not found
- failed to resolve CSS @import "%s"; %s
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/c12f91ba58616ccd.json.
Report an issue: GitHub ↗.