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

  1. 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.
  2. Verify what Hugo resolved: check node_modules/.bin/<name> and confirm it points at a .js entry (head the file / readlink).
  3. Ensure a native binary of the same name earlier in PATH isn't shadowing the Node package's executable.
  4. 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

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


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/c12f91ba58616ccd.json. Report an issue: GitHub ↗.