nektos/act · error

Cannot find: 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.

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.

Appendix: 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)