nektos/act · error
missing steps in composite action
Error message
missing steps in composite action
What it means
execAsComposite (pkg/runner/action_composite.go) runs the composite action's main steps. It calls step.getCompositeRunContext(ctx) then step.getCompositeSteps(); if steps is nil or steps.main is nil it errors, because a composite action with no main steps cannot execute. steps is populated from the action model's Runs.Steps — so this means the loaded action.yml has 'using: composite' but no (or unparsable) 'runs.steps'.
Source
Thrown at pkg/runner/action_composite.go:94
EventJSON: parent.EventJSON,
nodeToolFullPath: parent.nodeToolFullPath,
}
compositerc.ExprEval = compositerc.NewExpressionEvaluator(ctx)
return compositerc
}
func execAsComposite(step actionStep) common.Executor {
rc := step.getRunContext()
action := step.getActionModel()
return func(ctx context.Context) error {
compositeRC := step.getCompositeRunContext(ctx)
steps := step.getCompositeSteps()
if steps == nil || steps.main == nil {
return fmt.Errorf("missing steps in composite action")
}
ctx = WithCompositeLogger(ctx, &compositeRC.Masks)
err := steps.main(ctx)
// Map outputs from composite RunContext to job RunContext
eval := compositeRC.NewExpressionEvaluator(ctx)
for outputName, output := range action.Outputs {
rc.setOutput(ctx, map[string]string{
"name": outputName,
}, eval.Interpolate(ctx, output.Value))
}
rc.Masks = append(rc.Masks, compositeRC.Masks...)
rc.ExtraPath = compositeRC.ExtraPath
// compositeRC.Env is dirty, contains INPUT_ and merged step env, only rely on compositeRC.GlobalEnv
mergeIntoMap := mergeIntoMapCaseSensitiveView on GitHub (pinned to 4f41128141)
Solutions
- Add a non-empty 'steps:' list under 'runs:' in the composite action's action.yml.
- Validate YAML structure: 'runs' must contain 'using: composite' and 'steps:' as a list of step objects.
- Verify the local 'uses:' path resolves to the directory holding action.yml.
- Clear cache for remote actions and re-fetch at a ref where the action.yml is correct.
Example fix
# before (action.yml)
name: my-action
runs:
using: composite
# after
name: my-action
runs:
using: composite
steps:
- run: echo hi
shell: bash Defensive patterns
Strategy: validation
Validate before calling
python3 - <<'EOF'
import yaml,sys
a=yaml.safe_load(open('action.yml'))
runs=a.get('runs',{})
assert runs.get('using')=='composite', 'not composite'
assert isinstance(runs.get('steps'),list) and runs['steps'], 'runs.steps missing/empty'
print('composite action.yml ok')
EOF Prevention
- CI-validate action.yml schema for composite actions.
- Use actionlint on workflows and actions.
- Ensure local uses: paths point at the action.yml directory.
When it happens
Trigger: action.yml contains 'runs: using: composite' with a missing or empty 'steps:' key; steps failed to unmarshal (wrong indentation, non-list value); or the action model was loaded from an empty/incorrect file at the action path.
Common situations: Hand-written action.yml that forgets 'steps:' under 'runs:'; copy-paste from a Docker action leaving 'image:' but no composite steps; local action directory path wrong so an unrelated/blank action.yml is read.
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/be0bbbe2dc069f45.
Report an issue: GitHub.