nektos/act · error
--health-retries cannot be negative
Error message
--health-retries cannot be negative
What it means
Error [88]: The step's command inside the container exited with code 127 — the shell's 'command not found' code. Act maps it explicitly and links nektos/act#107 because it almost always means the image lacks /bin/bash (or the requested shell) and steps fail on every 'shell: bash' run. This is not a Docker API error; it is the job command failing in-image.
Source
Thrown at pkg/container/docker_cli.go:592
copts.healthStartInterval != 0
if copts.noHealthcheck {
if haveHealthSettings {
return nil, errors.New("--no-healthcheck conflicts with --health-* options")
}
healthConfig = &container.HealthConfig{Test: []string{"NONE"}}
} else if haveHealthSettings {
var probe []string
if copts.healthCmd != "" {
probe = []string{"CMD-SHELL", copts.healthCmd}
}
if copts.healthInterval < 0 {
return nil, errors.New("--health-interval cannot be negative")
}
if copts.healthTimeout < 0 {
return nil, errors.New("--health-timeout cannot be negative")
}
if copts.healthRetries < 0 {
return nil, errors.New("--health-retries cannot be negative")
}
if copts.healthStartPeriod < 0 {
return nil, errors.New("--health-start-period cannot be negative")
}
if copts.healthStartInterval < 0 {
return nil, errors.New("--health-start-interval cannot be negative")
}
healthConfig = &container.HealthConfig{
Test: probe,
Interval: copts.healthInterval,
Timeout: copts.healthTimeout,
StartPeriod: copts.healthStartPeriod,
StartInterval: copts.healthStartInterval,
Retries: copts.healthRetries,
}
}
View on GitHub (pinned to 4f41128141)
Solutions
- Install bash in the image or switch the image to one with bash (debian/ubuntu based)
- Set the step shell explicitly: shell: sh (or ash) for alpine images
- Use 'runs-on: ubuntu-latest' (act maps to its default images with bash) for bash-dependent steps
- For local actions, make entrypoint scripts POSIX sh compatible
Example fix
# before
jobs:
build:
runs-on: ubuntu-latest
container: alpine:latest
steps:
- run: echo hi # defaults to bash
# after
steps:
- run: echo hi
shell: sh Defensive patterns
Strategy: validation
Validate before calling
// Choose shell per image family before running
func shellFor(image string) string {
if strings.Contains(image, "alpine") || strings.Contains(image, "busybox") {
return "sh"
}
return "bash"
} Type guard
func imageHasBash(image string) bool {
// check via docker if scripting
out, err := exec.Command("docker", "run", "--rm", image, "sh", "-c", "command -v bash").Output()
return err == nil && len(out) > 0
} Try / catch
if err := step(ctx); err != nil && strings.Contains(err.Error(), "exitcode '127'") {
// set shell: sh on the step and re-run
} Prevention
- Default to shell: sh in workflows that target alpine
- Install bash in custom base images
- Test local action entrypoints with sh, not bash
When it happens
Trigger: A workflow step uses shell: bash (act's default for run:) in an image without bash (alpine, distroless, scratch); the entrypoint script references a missing binary; a local action's entrypoint uses bash while the job container is alpine.
Common situations: Default act images aside, using runs-on container images like alpine where only sh/ash exist; distroless images; images where bash is not on PATH; scripts with a #!/bin/bash shebang run via 'sh -c'.
Related errors
- --health-timeout cannot be negative
- --health-start-period cannot be negative
- conflicting options: cannot specify both --link-local-ip and
- --pid: invalid PID mode
- --uts: invalid UTS mode
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/a6a24aa3e6533392.
Report an issue: GitHub.