nektos/act · error
❌ Error in continue-on-error-expression: "continue-on-err
Error message
❌ Error in continue-on-error-expression: "continue-on-error: %s" (%s)
What it means
A step's `continue-on-error:` value could not be evaluated as a boolean expression. isContinueOnError skips empty values but runs anything else through EvalBool with DefaultStatusCheckNone; non-boolean results or evaluation errors (bad syntax, unknown context) produce this error.
Source
Thrown at pkg/runner/step.go:325
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)
}
return continueOnError, nil
}
func mergeIntoMap(step step, target *map[string]string, maps ...map[string]string) {
if rc := step.getRunContext(); rc != nil && rc.JobContainer != nil && rc.JobContainer.IsEnvironmentCaseInsensitive() {
mergeIntoMapCaseInsensitive(*target, maps...)
} else {
mergeIntoMapCaseSensitive(*target, maps...)
}
}
func mergeIntoMapCaseSensitive(target map[string]string, maps ...map[string]string) {
for _, m := range maps {
for k, v := range m {
target[k] = v
}View on GitHub (pinned to 4f41128141)
Solutions
- Make the expression strictly boolean: compare strings explicitly (`== 'true'`) instead of relying on truthiness of arbitrary strings.
- Verify function names and context availability at step scope.
- Test by temporarily replacing the expression with a literal true/false to confirm the rest of the step works.
Example fix
# before
continue-on-error: ${{ steps.setup.outputs.retrying }} # 'yes' is not boolean
# after
continue-on-error: ${{ steps.setup.outputs.retrying == 'yes' }} Defensive patterns
Strategy: validation
Validate before calling
# ensure continue-on-error is boolean-valued: prefer
# continue-on-error: ${{ expr == 'value' }}
# never a bare non-boolean output reference Prevention
- Always wrap string outputs in an explicit == comparison.
- Test expressions with a literal true first.
- actionlint catches malformed expressions here too.
When it happens
Trigger: `continue-on-error: ${{ ... }}` where the expression returns a non-boolean (string/number) that the evaluator refuses, references undefined contexts, or contains a syntax error; also plain strings that aren't valid expressions after implicit conversion rules.
Common situations: Setting `continue-on-error: ${{ steps.check.outputs.retry }}` where output is 'yes'/'no' instead of 'true'/'false'; complex ternary expressions with typos; referencing contexts not available at that point in evaluation.
Related errors
- ❌ Error in if-expression: "if: %s" (%s)
- ❌ Error in if-expression: "if: %s" (%s)
- 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/6923d2b95e523e52.
Report an issue: GitHub.