[GH-ISSUE #5972] Conditional steps using expressions with variables always evaluate to 'true' #1307

Closed
opened 2026-03-01 21:50:16 +03:00 by kerem · 3 comments
Owner

Originally created by @mfncooper on GitHub (Nov 21, 2025).
Original GitHub issue: https://github.com/nektos/act/issues/5972

Bug report info

act version:            0.2.82
GOOS:                   windows
GOARCH:                 amd64
NumCPU:                 2
Docker host:            DOCKER_HOST environment variable is not set
Sockets found:
        \\.\pipe\docker_engine(broken)
Config files:
        C:\Users\user1\AppData\Local\act\actrc:
                -P ubuntu-latest=catthehacker/ubuntu:act-latest
                -P ubuntu-22.04=catthehacker/ubuntu:act-22.04
                -P ubuntu-20.04=catthehacker/ubuntu:act-20.04
                -P ubuntu-18.04=catthehacker/ubuntu:act-18.04
Build info:
        Go version:            go1.24.0
        Module path:           github.com/nektos/act
        Main version:          v0.2.82
        Main path:             github.com/nektos/act
        Main checksum:
        Build settings:
                -buildmode:           exe
                -compiler:            gc
                -ldflags:             -s -w -X main.version=0.2.82 -X main.commit=3d71542867d7cbdac6a75e540be6f64362e94d
e2 -X main.date=2025-10-01T02:36:39Z -X main.builtBy=goreleaser
                CGO_ENABLED:          0
                GOARCH:               amd64
                GOOS:                 windows
                GOAMD64:              v1
                vcs:                  git
                vcs.revision:         3d71542867d7cbdac6a75e540be6f64362e94de2
                vcs.time:             2025-10-01T02:36:13Z
                vcs.modified:         false
Docker Engine:
        Engine version:        28.5.2
        Engine runtime:        runc
        Cgroup version:        2
        Cgroup driver:         cgroupfs
        Storage driver:        overlayfs
        Registry URI:          https://index.docker.io/v1/
        OS:                    Docker Desktop
        OS type:               linux
        OS version:
        OS arch:               x86_64
        OS kernel:             6.6.87.2-microsoft-standard-WSL2
        OS CPU:                2
        OS memory:             3863 MB
        Security options:
                name=seccomp,profile=builtin
                name=cgroupns

Command used with act

act -W ./.github/workflows/local-test.yml -P windows-latest=-self-hosted -v

Describe issue

When using a variable in the expression for a conditional step, the expression evaluation is broken, and the condition always evaluates to true. For example, in the workflow below, this condition should always be false, since the job name is local-test-job, which obviously does not contain foo:

    if: contains(${{github.job}}, 'foo')

However, it always evaluates to true (or at least an expression that is treated as true). The expression evaluation process retrieves the correct value from the variable, as seen in the log, but then it does not finish formatting the result and evaluating the expression. It seems as if it stops short of one more required evaluation step.

Evaluation using contains() with hardcoded values works correctly, so it is the use of variables that is causing the issue. The log output for hardcoded expressions, both successful and not, are included below.

This problem is not specific to the use of github.job. I need to be able to use it with, for example, matrix.config.name, but that exhibits the same issue. That's consistent with the value of the variable being retrieved correctly but the remainder of the evaluation not being properly completed.

The problem is also not Windows-specific. I ran the same workflow with ubuntu-latest and an appropriately adjusted command line (i.e. without the -P piece), and saw the same result.

No response

Workflow content

name: Local Test Workflow

on: [pull_request]

jobs:
  local-test-job:
    runs-on: windows-latest
    steps:
      - name: Conditional step based on expression
        if: contains(${{github.job}}, 'foo')
        run: echo "Expression should evaluate to false. This message should never appear."

      - name: Conditional step with hardcoded values
        if: contains('foobarbaz', 'baz')
        run: echo "Hardcoded for success. This message should always appear."

      - name: Conditional with hardcoded values (not found)
        if: contains('foobarbaz', 'nope')
        run: echo "Hardcoded for failure. This message should never appear."

Relevant log output

Failing evaluation:

[Local Test Workflow/local-test-job] [DEBUG] expression 'contains(${{github.job}}, 'foo')' rewritten to 'format('contains({0}, ''foo'')', github.job)'
[Local Test Workflow/local-test-job] [DEBUG] evaluating expression 'format('contains({0}, ''foo'')', github.job)'
[Local Test Workflow/local-test-job] [DEBUG] expression 'format('contains({0}, ''foo'')', github.job)' evaluated to '%!t(string=contains(local-test-job, 'foo'))'
[Local Test Workflow/local-test-job] ⭐ Run Main Conditional step based on expression

| Expression should evaluate to false. This message should never appear.
[Local Test Workflow/local-test-job]   ✅  Success - Main Conditional step based on expression [2.2689777s]

Successful evaluations:

[Local Test Workflow/local-test-job] [DEBUG] evaluating expression 'contains('foobarbaz', 'baz')'
[Local Test Workflow/local-test-job] [DEBUG] expression 'contains('foobarbaz', 'baz')' evaluated to 'true'
[Local Test Workflow/local-test-job] ⭐ Run Main Conditional step with hardcoded values
| Hardcoded for success. This message should always appear.
[Local Test Workflow/local-test-job]   ✅  Success - Main Conditional step with hardcoded values [1.6741982s]

[Local Test Workflow/local-test-job] [DEBUG] evaluating expression 'contains('foobarbaz', 'nope')'
[Local Test Workflow/local-test-job] [DEBUG] expression 'contains('foobarbaz', 'nope')' evaluated to 'false'
[Local Test Workflow/local-test-job] [DEBUG] Skipping step 'Conditional with hardcoded values (not found)' due to 'contains('foobarbaz', 'nope')'

Additional information

No response

Originally created by @mfncooper on GitHub (Nov 21, 2025). Original GitHub issue: https://github.com/nektos/act/issues/5972 ### Bug report info ```plain text act version: 0.2.82 GOOS: windows GOARCH: amd64 NumCPU: 2 Docker host: DOCKER_HOST environment variable is not set Sockets found: \\.\pipe\docker_engine(broken) Config files: C:\Users\user1\AppData\Local\act\actrc: -P ubuntu-latest=catthehacker/ubuntu:act-latest -P ubuntu-22.04=catthehacker/ubuntu:act-22.04 -P ubuntu-20.04=catthehacker/ubuntu:act-20.04 -P ubuntu-18.04=catthehacker/ubuntu:act-18.04 Build info: Go version: go1.24.0 Module path: github.com/nektos/act Main version: v0.2.82 Main path: github.com/nektos/act Main checksum: Build settings: -buildmode: exe -compiler: gc -ldflags: -s -w -X main.version=0.2.82 -X main.commit=3d71542867d7cbdac6a75e540be6f64362e94d e2 -X main.date=2025-10-01T02:36:39Z -X main.builtBy=goreleaser CGO_ENABLED: 0 GOARCH: amd64 GOOS: windows GOAMD64: v1 vcs: git vcs.revision: 3d71542867d7cbdac6a75e540be6f64362e94de2 vcs.time: 2025-10-01T02:36:13Z vcs.modified: false Docker Engine: Engine version: 28.5.2 Engine runtime: runc Cgroup version: 2 Cgroup driver: cgroupfs Storage driver: overlayfs Registry URI: https://index.docker.io/v1/ OS: Docker Desktop OS type: linux OS version: OS arch: x86_64 OS kernel: 6.6.87.2-microsoft-standard-WSL2 OS CPU: 2 OS memory: 3863 MB Security options: name=seccomp,profile=builtin name=cgroupns ``` ### Command used with act ```sh act -W ./.github/workflows/local-test.yml -P windows-latest=-self-hosted -v ``` ### Describe issue When using a variable in the expression for a conditional step, the expression evaluation is broken, and the condition always evaluates to `true`. For example, in the workflow below, this condition should always be `false`, since the job name is `local-test-job`, which obviously does not contain `foo`: ```yml if: contains(${{github.job}}, 'foo') ``` However, it always evaluates to `true` (or at least an expression that is treated as `true`). The expression evaluation process retrieves the correct value from the variable, as seen in the log, but then it does not finish formatting the result and evaluating the expression. It seems as if it stops short of one more required evaluation step. Evaluation using `contains()` with hardcoded values works correctly, so it is the use of variables that is causing the issue. The log output for hardcoded expressions, both successful and not, are included below. This problem is not specific to the use of `github.job`. I need to be able to use it with, for example, `matrix.config.name`, but that exhibits the same issue. That's consistent with the value of the variable being retrieved correctly but the remainder of the evaluation not being properly completed. The problem is also *not* Windows-specific. I ran the same workflow with `ubuntu-latest` and an appropriately adjusted command line (i.e. without the `-P` piece), and saw the same result. ### Link to GitHub repository _No response_ ### Workflow content ```yml name: Local Test Workflow on: [pull_request] jobs: local-test-job: runs-on: windows-latest steps: - name: Conditional step based on expression if: contains(${{github.job}}, 'foo') run: echo "Expression should evaluate to false. This message should never appear." - name: Conditional step with hardcoded values if: contains('foobarbaz', 'baz') run: echo "Hardcoded for success. This message should always appear." - name: Conditional with hardcoded values (not found) if: contains('foobarbaz', 'nope') run: echo "Hardcoded for failure. This message should never appear." ``` ### Relevant log output ```sh Failing evaluation: [Local Test Workflow/local-test-job] [DEBUG] expression 'contains(${{github.job}}, 'foo')' rewritten to 'format('contains({0}, ''foo'')', github.job)' [Local Test Workflow/local-test-job] [DEBUG] evaluating expression 'format('contains({0}, ''foo'')', github.job)' [Local Test Workflow/local-test-job] [DEBUG] expression 'format('contains({0}, ''foo'')', github.job)' evaluated to '%!t(string=contains(local-test-job, 'foo'))' [Local Test Workflow/local-test-job] ⭐ Run Main Conditional step based on expression | Expression should evaluate to false. This message should never appear. [Local Test Workflow/local-test-job] ✅ Success - Main Conditional step based on expression [2.2689777s] Successful evaluations: [Local Test Workflow/local-test-job] [DEBUG] evaluating expression 'contains('foobarbaz', 'baz')' [Local Test Workflow/local-test-job] [DEBUG] expression 'contains('foobarbaz', 'baz')' evaluated to 'true' [Local Test Workflow/local-test-job] ⭐ Run Main Conditional step with hardcoded values | Hardcoded for success. This message should always appear. [Local Test Workflow/local-test-job] ✅ Success - Main Conditional step with hardcoded values [1.6741982s] [Local Test Workflow/local-test-job] [DEBUG] evaluating expression 'contains('foobarbaz', 'nope')' [Local Test Workflow/local-test-job] [DEBUG] expression 'contains('foobarbaz', 'nope')' evaluated to 'false' [Local Test Workflow/local-test-job] [DEBUG] Skipping step 'Conditional with hardcoded values (not found)' due to 'contains('foobarbaz', 'nope')' ``` ### Additional information _No response_
kerem 2026-03-01 21:50:16 +03:00
  • closed this issue
  • added the
    kind/bug
    label
Author
Owner

@ChristopherHX commented on GitHub (Nov 22, 2025):

Isn't this exactly what happens if you do this on GitHub Actions?

Never include ${{ }} in the middle of action if conditions. You do not need them to access variables inside an condition.

<!-- gh-comment-id:3567141412 --> @ChristopherHX commented on GitHub (Nov 22, 2025): Isn't this exactly what happens if you do this on GitHub Actions? Never include `${{` `}}` in the middle of action if conditions. You do not need them to access variables inside an condition.
Author
Owner

@ChristopherHX commented on GitHub (Nov 22, 2025):

Well act could literally reject your workflow, but then someone might complain why does it not run while this works fine on GitHub Actions

<!-- gh-comment-id:3567142373 --> @ChristopherHX commented on GitHub (Nov 22, 2025): Well act could literally reject your workflow, but then someone might complain why does it not run while this works fine on GitHub Actions
Author
Owner

@mfncooper commented on GitHub (Nov 23, 2025):

I completely missed, in the rather incomplete GitHub Docs, that it's the entire expression that goes between ${{ and }}, and not just the variable name, and that you can also omit them entirely. Sorry for the noise.

<!-- gh-comment-id:3567403638 --> @mfncooper commented on GitHub (Nov 23, 2025): I completely missed, in the rather incomplete GitHub Docs, that it's the entire expression that goes between `${{` and `}}`, and not just the variable name, and that you can also omit them entirely. Sorry for the noise.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/act#1307
No description provided.