gohugoio/hugo · error

failed to execute binary

Error message

failed to execute binary %q with args %v: %s

What it means

Returned by cmdWrapper.Run when the underlying `os/exec` command fails for any reason other than a 'not found' message on stderr. The message embeds the binary name, the full args vector (excluding the binary itself), and the captured stderr buffer so the caller sees the tool's own error output.

Solutions

  1. Read the embedded stderr text in the message; it is the tool's own error.
  2. Run the same binary with the same args manually in a shell to reproduce.
  3. If the text mentions EPERM/permission-model, widen security.exec.allow or Node permissions config.
  4. Check that all asset files referenced by the tool exist on disk.

Example fix

// before
if err := runner.Run(); err != nil { return err }
// after
if err := runner.Run(); err != nil {
  var nf *hexec.NotFoundError
  if errors.As(err, &nf) { /* missing binary path */ }
  return fmt.Errorf("asset build failed: %w", err)
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := runner.Run(); err != nil {
  var nf *hexec.NotFoundError
  if errors.As(err, &nf) { /* install/PATH guidance */ }
  // err already contains the tool's stderr; log and fail the asset build
  return fmt.Errorf("build tool %q failed: %w", name, err)
}

Prevention

When it happens

Trigger: Calling Runner.Run() on a command built via Exec.New/Npx where the external process exits non-zero: a PostCSS config error, a missing asset referenced by the tool, a Node.js permission-model denial, a segfault, or invalid CLI flags.

Common situations: Asset processing pipelines (toCSS, PostCSS, Babel, Tailwind) failing because of a config error in the underlying tool, an unreachable import, or Node.js --permission denials when the security.allow list is too strict.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/8830d2cdf716e8cc. Report an issue: GitHub.

Appendix: source

Thrown at common/hexec/exec.go:463

type cmdWrapper struct {
	name string
	c    *exec.Cmd

	outerr *bytes.Buffer
}

var notFoundRe = regexp.MustCompile(`(?s)not found:|could not determine executable`)

func (c *cmdWrapper) Run() error {
	err := c.c.Run()
	if err == nil {
		return nil
	}
	if notFoundRe.MatchString(c.outerr.String()) {
		return &NotFoundError{name: c.name, method: "in PATH"}
	}
	return fmt.Errorf("failed to execute binary %q with args %v: %s", c.name, c.c.Args[1:], c.outerr.String())
}

func (c *cmdWrapper) StdinPipe() (io.WriteCloser, error) {
	return c.c.StdinPipe()
}

type commandeer struct {
	stdout io.Writer
	stderr io.Writer
	stdin  io.Reader
	dir    string
	ctx    context.Context

	name               string
	fullyQualifiedName string
	env                []string
}

View on GitHub (pinned to 52c9bd7908)