nektos/act · error

Cannot find: {cmd} in PATH

Error message

Cannot find: {cmd} in PATH

What it means

lookupPathHost resolves a executable name using lookpath.LookPath2 against the job's effective environment (PATH included). If the command is not found in any PATH directory, it writes 'Cannot find: <cmd> in PATH' to the step's output writer and returns it as an error. This is the host-execution (-self-hosted/--bind) equivalent of 'command not found', with the job's env applied rather than your interactive shell's.

Source

Thrown at pkg/container/host_environment.go:228

	if runtime.GOOS == "windows" {
		for k, v := range l.env {
			if strings.EqualFold(name, k) {
				return v
			}
		}
		return ""
	}
	return l.env[name]
}

func lookupPathHost(cmd string, env map[string]string, writer io.Writer) (string, error) {
	f, err := lookpath.LookPath2(cmd, &localEnv{env: env})
	if err != nil {
		err := "Cannot find: " + fmt.Sprint(cmd) + " in PATH"
		if _, _err := writer.Write([]byte(err + "\n")); _err != nil {
			return "", fmt.Errorf("%v: %w", err, _err)
		}
		return "", errors.New(err)
	}
	return f, nil
}

func setupPty(cmd *exec.Cmd, cmdline string) (*os.File, *os.File, error) {
	ppty, tty, err := openPty()
	if err != nil {
		return nil, nil, err
	}
	if term.IsTerminal(int(tty.Fd())) {
		_, err := term.MakeRaw(int(tty.Fd()))
		if err != nil {
			ppty.Close()
			tty.Close()
			return nil, nil, err
		}
	}
	cmd.Stdin = tty

View on GitHub (pinned to 4f41128141)

Solutions

  1. Install the missing tool on the host and ensure its bin directory is on PATH (verify with 'act -P ...=-self-hosted' then 'which <cmd>' in a debug step: 'run: echo $PATH; command -v <cmd>').
  2. Set PATH explicitly at the job or step level: 'env: PATH: /home/runner/.local/bin:$PATH' (or prepend in the run script).
  3. Use absolute paths to the binary in the run step if the location is known.
  4. Prefer running the workflow in a container image that already contains the tool instead of host mode.

Example fix

# before
- run: terraform plan
# host mode: Cannot find: terraform in PATH

# after
- run: terraform plan
  env:
    PATH: /opt/homebrew/bin:/usr/local/bin:/home/runner/.local/bin:${PATH}
Defensive patterns

Strategy: validation

Validate before calling

// Verify a tool is resolvable with the env act will use, before the step runs
package main

import (
	"fmt"
	"os"
	"os/exec"
)

func checkToolOnPath(tool string, env map[string]string) error {
	cmd := exec.Command("sh", "-c", "command -v "+tool)
	cmd.Env = os.Environ()
	for k, v := range env {
		cmd.Env = append(cmd.Env, k+"="+v)
	}
	if out, err := cmd.Output(); err != nil {
		return fmt.Errorf("%s not on PATH under job env; install it or extend PATH", tool)
	} else {
		fmt.Printf("%s resolves to %s\n", tool, out)
	}
	return nil
}

Try / catch

if err := stepExecutor(ctx); err != nil {
    if strings.Contains(err.Error(), "Cannot find:") && strings.Contains(err.Error(), "in PATH") {
        cmd := strings.TrimPrefix(strings.Split(err.Error(), " in PATH")[0], "Cannot find: ")
        return fmt.Errorf("install %s on the host or prepend its directory to PATH in the step env", cmd)
    }
    return err
}

Prevention

When it happens

Trigger: A run step executing a tool absent from the PATH act passes to host execution: e.g. 'run: terraform plan' with no terraform installed, or a tool installed in a shell-rc-only path (e.g. ~/.local/bin added by .bashrc) that act's environment does not include; also commands installed only inside containers while running -self-hosted.

Common situations: Switching a workflow from container to -self-hosted mode and assuming tools from the container image exist on the host; tools installed via user-level managers (cargo, npm -g with a prefix, asdf, mise) whose shims live outside act's PATH; macOS/Linux differences in default PATH; CI agents with minimal PATHs.

Related errors


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/6a2c6d20fcd58e41. Report an issue: GitHub.