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

  1. Read the inner error text in parentheses — it pinpoints the parse/eval failure.
  2. Check the expression for syntax issues: balanced `${{ }}`, `==` not `=`, quoted strings.
  3. Confirm every context used exists at step scope (steps, env, matrix, github, runner, needs-if-declared, job, inputs for reusable workflows).
  4. 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

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


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/867a1a0c25526d5c. Report an issue: GitHub.