nektos/act · error
missing steps in composite action
Error message
missing steps in composite action
What it means
Thrown in the pre stage of a composite action step (pkg/runner/action.go). Before running, act lazily builds the composite RunContext via step.getCompositeRunContext(ctx) and then expects getCompositeSteps() to yield a populated steps struct with a non-nil pre executor. If steps is nil (run context construction failed silently, e.g. action metadata could not be read) or steps.pre is nil (the composite action's action.yml defines no 'pre' step is acceptable — pre is then simply skipped), the nil-steps case is reported as 'missing steps in composite action'.
Source
Thrown at pkg/runner/action.go:580
return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx)
case x.IsDocker():
if remoteAction == nil {
actionDir = ""
actionPath = containerActionDir
}
return execAsDocker(ctx, step, actionName, actionDir, actionPath, remoteAction == nil, "pre-entrypoint")
case x.IsComposite():
if step.getCompositeSteps() == nil {
step.getCompositeRunContext(ctx)
}
if steps := step.getCompositeSteps(); steps != nil && steps.pre != nil {
return steps.pre(ctx)
}
return fmt.Errorf("missing steps in composite action")
default:
return nil
}
}
}
func shouldRunPostStep(step actionStep) common.Conditional {
return func(ctx context.Context) bool {
log := common.Logger(ctx)
stepResults := step.getRunContext().getStepsContext()
stepResult := stepResults[step.getStepModel().ID]
if stepResult == nil {
log.WithField("stepResult", model.StepStatusSkipped).Debugf("skipping post step for '%s'; step was not executed", step.getStepModel())
return false
}
View on GitHub (pinned to 4f41128141)
Solutions
- Check the referenced action's action.yml exists and has 'runs: using: composite' with a non-empty 'runs.steps' list.
- For local actions, verify the 'uses:' path points at the directory containing action.yml (relative to the repo root, e.g. uses: ./.github/actions/my-action).
- For remote actions, verify the ref exists and the repo root actually contains action.yml; clear the action cache (~/.cache/act) in case of a corrupt clone.
- Validate the YAML parses (e.g. 'python -c "import yaml,sys;yaml.safe_load(open('action.yml'))"' or yamllint) — a YAML syntax error can leave steps unset.
Example fix
# before (action.yml)
runs:
using: composite
# no steps key
# after
runs:
using: composite
steps:
- run: echo hello
shell: bash Defensive patterns
Strategy: validation
Validate before calling
# before running act, assert the composite action metadata exists and has steps
ACTION_DIR=.github/actions/my-action
[ -f "$ACTION_DIR/action.yml" ] || { echo "missing $ACTION_DIR/action.yml"; exit 1; }
grep -q 'using: composite' "$ACTION_DIR/action.yml" && grep -qE '^\s+steps:' "$ACTION_DIR/action.yml" Prevention
- Lint actions with actionlint before committing.
- Always include a non-empty runs.steps in composite action.yml.
- Point uses: at the directory containing action.yml.
When it happens
Trigger: A 'uses: local/remote-composite-action' step whose action.yml is missing, malformed, unreadable, or contains no 'runs.steps' section; step.getCompositeRunContext succeeds but populate-step recursion (which calls newCompositeRunContext and builds steps) leaves getCompositeSteps() nil.
Common situations: Composite action metadata (action.yml/action.yaml) not committed, wrong path for a local action, remote composite action cloned to an empty dir, or an action.yml whose 'runs' block uses 'using: composite' but omits 'steps'.
Related errors
- missing steps in composite action
- invalid Step %v: missing run or uses key
- expected format {owner}/{repo}/.github/workflows/{filename}@
- ErrShortRef
- find cache: %w
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/c80734159d298748.
Report an issue: GitHub.