nektos/act · error
❌ Error in if-expression: "if: %s" (%s)
Error message
❌ Error in if-expression: "if: %s" (%s)
What it means
A step-level `if:` expression failed to evaluate. isStepEnabled runs the expression through NewStepExpressionEvaluatorExt with DefaultStatusCheckSuccess (or Always for the post stage); a syntax error, unknown context/function, or type error yields this error, which usually marks the step and job failed unless continue-on-error applies.
Source
Thrown at pkg/runner/step.go:309
delete(*env, key)
}
}
}
}
func isStepEnabled(ctx context.Context, expr string, step step, stage stepStage) (bool, error) {
rc := step.getRunContext()
var defaultStatusCheck exprparser.DefaultStatusCheck
if stage == stepStagePost {
defaultStatusCheck = exprparser.DefaultStatusCheckAlways
} else {
defaultStatusCheck = exprparser.DefaultStatusCheckSuccess
}
runStep, err := EvalBool(ctx, rc.NewStepExpressionEvaluatorExt(ctx, step, stage == stepStageMain), expr, defaultStatusCheck)
if err != nil {
return false, fmt.Errorf(" \u274C Error in if-expression: \"if: %s\" (%s)", expr, err)
}
return runStep, nil
}
func isContinueOnError(ctx context.Context, expr string, step step, _ stepStage) (bool, error) {
// https://github.com/github/docs/blob/3ae84420bd10997bb5f35f629ebb7160fe776eae/content/actions/reference/workflow-syntax-for-github-actions.md?plain=true#L962
if len(strings.TrimSpace(expr)) == 0 {
return false, nil
}
rc := step.getRunContext()
continueOnError, err := EvalBool(ctx, rc.NewStepExpressionEvaluator(ctx, step), expr, exprparser.DefaultStatusCheckNone)
if err != nil {
return false, fmt.Errorf(" \u274C Error in continue-on-error-expression: \"continue-on-error: %s\" (%s)", expr, err)
}
View on GitHub (pinned to 4f41128141)
Solutions
- Read the inner error text in parentheses — it pinpoints the parse/eval failure.
- Check the expression for syntax issues: balanced `${{ }}`, `==` not `=`, quoted strings.
- Confirm every context used exists at step scope (steps, env, matrix, github, runner, needs-if-declared, job, inputs for reusable workflows).
- If a recently added GitHub function is used, check act's exprparser support or pin to functions act implements.
Example fix
# before
- if: ${{ steps.checks.outputs.ok == 'true' && }} # dangling operator
# after
- if: ${{ steps.checks.outputs.ok == 'true' }} Defensive patterns
Strategy: validation
Validate before calling
- run: actionlint .github/workflows/workflow.yml # catches invalid step if-expressions
Prevention
- Keep step if-expressions minimal and step-scoped.
- Verify step ids referenced in if-expressions exist.
- Quote string comparisons (== 'true').
When it happens
Trigger: `steps.<id>.if:` references an unavailable context (e.g. `needs` inside a non-dependent job, or a matrix key that doesn't exist), has invalid syntax, uses an undefined function, or compares incompatible types in a way the exprparser rejects.
Common situations: `if: ${{ steps.x.outputs.y }}` where step id `x` is misspelled (returns null rather than erroring — but a typo'd function or unbalanced parens does error); copying job-level expressions with `needs.*.result` when `needs` is absent; expressions using newer GitHub functions not yet implemented in act's exprparser version.
Related errors
- ❌ Error in if-expression: "if: %s" (%s)
- ❌ Error in continue-on-error-expression: "continue-on-err
- Invalid run/uses syntax for job:%s step:%+v
- --pid: invalid PID mode
- invalid storage option
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/867a1a0c25526d5c.
Report an issue: GitHub.