nektos/act · error

❌ Error in if-expression: "if: %s" (%s)

Error message

  ❌  Error in if-expression: "if: %s" (%s)

What it means

The job-level `if:` expression could not be evaluated. EvalBool runs the expression through act's exprparser; a syntax error, unknown function/context, or type error inside the `${{ }}` expression causes the parser to return an error, which act surfaces prefixed with the failing expression text.

Source

Thrown at pkg/runner/run_context.go:800

func (rc *RunContext) options(ctx context.Context) string {
	job := rc.Run.Job()
	c := job.Container()
	if c != nil {
		return rc.ExprEval.Interpolate(ctx, c.Options)
	}

	return rc.Config.ContainerOptions
}

func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
	job := rc.Run.Job()
	l := common.Logger(ctx)
	runJob, runJobErr := EvalBool(ctx, rc.ExprEval, job.If.Value, exprparser.DefaultStatusCheckSuccess)
	jobType, jobTypeErr := job.Type()

	if runJobErr != nil {
		return false, fmt.Errorf("  \u274C  Error in if-expression: \"if: %s\" (%s)", job.If.Value, runJobErr)
	}

	if jobType == model.JobTypeInvalid {
		return false, jobTypeErr
	}

	if !runJob {
		rc.result("skipped")
		l.WithField("jobResult", "skipped").Debugf("Skipping job '%s' due to '%s'", job.Name, job.If.Value)
		return false, nil
	}

	if jobType != model.JobTypeDefault {
		return true, nil
	}

	img := rc.platformImage(ctx)
	if img == "" {

View on GitHub (pinned to 4f41128141)

Solutions

  1. Read the parenthesized inner error — it names the exact parse/eval failure for the printed expression.
  2. Move step-scoped contexts (steps, needs outputs are fine at job level but steps are not) out of job-level `if:`; use `needs.<job>.outputs.*` instead.
  3. Validate expression syntax with actionlint, which understands GitHub's expression grammar.
  4. Simplify the expression to isolate the failing token (e.g. test `if: true` first, then add pieces back).

Example fix

# before
jobs:
  deploy:
    if: ${{ steps.build.outputs.ok == 'true' }}  # 'steps' undefined at job level
# after
jobs:
  deploy:
    needs: build
    if: ${{ needs.build.outputs.ok == 'true' }}
Defensive patterns

Strategy: validation

Validate before calling

# CI step: validate workflow expressions before execution
- run: actionlint -shellcheck= -pyflakes= .github/workflows/*.yml

Prevention

When it happens

Trigger: `jobs.<id>.if:` contains invalid expression syntax (unbalanced parens, bad operator), references a context or property not available at job level (e.g. steps context, which only exists for steps), uses an undefined function, or has a typo like `falsy()` instead of `always()`.

Common situations: Copy-pasting a step-level `if: ${{ steps.check.outputs.x }}` to the job level where `steps` does not exist; typos in function names; using runner.* or env.* properties that are not implemented in act; expressions valid on GitHub but relying on contexts act does not populate.

Related errors


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