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 = ttyView on GitHub (pinned to 4f41128141)
Solutions
- 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>').
- Set PATH explicitly at the job or step level: 'env: PATH: /home/runner/.local/bin:$PATH' (or prepend in the run script).
- Use absolute paths to the binary in the run step if the location is known.
- 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
- Add a debug step 'run: echo $PATH; command -v <tool>' before failing steps in host mode.
- Set PATH explicitly in job env when tools live in user-local bin dirs.
- Prefer container images that bundle required tools over host execution.
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
- --userns: invalid USER mode
- no name set for network
- Unsupported Operation
- unable to determine outbound IP address
- %s (%s): %w
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/6a2c6d20fcd58e41.
Report an issue: GitHub.