[GH-ISSUE #1482] Matrix expession evaluated when not expecting it to be #760

Open
opened 2026-03-01 21:46:09 +03:00 by kerem · 10 comments
Owner

Originally created by @20k-ultra on GitHub (Nov 29, 2022).
Original GitHub issue: https://github.com/nektos/act/issues/1482

Bug report info

act version:            0.2.33-12-ga108f10
GOOS:                   linux
GOARCH:                 amd64
NumCPU:                 16
Docker host:            DOCKER_HOST environment variable is unset/empty.
Sockets found:
	/var/run/docker.sock
Config files:           
	/home/mig/.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
	.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.19.3
	Module path:           command-line-arguments
	Main version:          
	Main path:             
	Main checksum:         
	Build settings:
		-compiler:            gc
		-ldflags:             -X main.version=0.2.33-12-ga108f10
		CGO_ENABLED:          1
		CGO_CFLAGS:           
		CGO_CPPFLAGS:         
		CGO_CXXFLAGS:         
		CGO_LDFLAGS:          
		GOARCH:               amd64
		GOOS:                 linux
		GOAMD64:              v1
Docker Engine:
	Engine version:        20.10.21
	Engine runtime:        runc
	Cgroup version:        2
	Cgroup driver:         systemd
	Storage driver:        overlay2
	Registry URI:          https://index.docker.io/v1/
	OS:                    Arch Linux
	OS type:               linux
	OS version:            
	OS arch:               x86_64
	OS kernel:             6.0.8-zen1-1-zen
	OS CPU:                16
	OS memory:             31784 MB
	Security options:
		name=seccomp,profile=default
		name=cgroupns

Command used with act

act -v push -W sample_workflow.yml

Describe issue

I have a step in my workflow which uses another job's output as a matrix parameter. The problem is that this job output is null can be null for specific conditions. I protect my step from trying to evaluate null within the matrix by using an if expression.

On Github, this setup is fine and the job is skipped as expected. With act, the job should be skipped also but instead, an error is thrown from not being able to unmarshal nil to JSON.

No response

Workflow content

on: push
jobs:
  versions:
    runs-on: ubuntu-latest
    outputs:
      python: ${{ steps.python_versions.outputs.json }}
    steps:
      - name: Set Python versions
        if: inputs.python_enabled == 'true'
        id: python_versions
        run: echo "json=[\"\^3.7\"]" >> $GITHUB_OUTPUT
  python_stuff:
    runs-on: ubuntu-latest
    needs:
      - versions
    if: inputs.python_enabled == 'true'
    strategy:
      matrix:
        python-version: ${{ fromJSON(needs.versions.outputs.python_versions) }}
    steps:
      - run: echo "doing stuff with ${{ matrix.python-version }}"

Relevant log output

DEBU[0000] evaluating expression '${{ fromJSON(needs.versions.outputs.python_versions) }}' 
DEBU[0000] expression '${{ fromJSON(needs.versions.outputs.python_versions) }}' evaluated to '%!t(<nil>)' 
ERRO[0000] Error while evaluating matrix: Cannot parse non-string type invalid as JSON 
DEBU[0000]                                              
FATA[0000] yaml: unmarshal errors:
  line 19: cannot unmarshal !!str `${{ fro...` into []interface {}

Additional information

Here is a link to github run: https://github.com/20k-ultra/action-tester/actions/runs/3580010001

Originally created by @20k-ultra on GitHub (Nov 29, 2022). Original GitHub issue: https://github.com/nektos/act/issues/1482 ### Bug report info ```plain text act version: 0.2.33-12-ga108f10 GOOS: linux GOARCH: amd64 NumCPU: 16 Docker host: DOCKER_HOST environment variable is unset/empty. Sockets found: /var/run/docker.sock Config files: /home/mig/.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 .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.19.3 Module path: command-line-arguments Main version: Main path: Main checksum: Build settings: -compiler: gc -ldflags: -X main.version=0.2.33-12-ga108f10 CGO_ENABLED: 1 CGO_CFLAGS: CGO_CPPFLAGS: CGO_CXXFLAGS: CGO_LDFLAGS: GOARCH: amd64 GOOS: linux GOAMD64: v1 Docker Engine: Engine version: 20.10.21 Engine runtime: runc Cgroup version: 2 Cgroup driver: systemd Storage driver: overlay2 Registry URI: https://index.docker.io/v1/ OS: Arch Linux OS type: linux OS version: OS arch: x86_64 OS kernel: 6.0.8-zen1-1-zen OS CPU: 16 OS memory: 31784 MB Security options: name=seccomp,profile=default name=cgroupns ``` ### Command used with act ```sh act -v push -W sample_workflow.yml ``` ### Describe issue I have a step in my workflow which uses another job's output as a matrix parameter. The problem is that this job output is null can be null for specific conditions. I protect my step from trying to evaluate null within the matrix by using an if expression. On Github, this setup is fine and the job is skipped as expected. With act, the job should be skipped also but instead, an error is thrown from not being able to unmarshal nil to JSON. ### Link to GitHub repository _No response_ ### Workflow content ```yml on: push jobs: versions: runs-on: ubuntu-latest outputs: python: ${{ steps.python_versions.outputs.json }} steps: - name: Set Python versions if: inputs.python_enabled == 'true' id: python_versions run: echo "json=[\"\^3.7\"]" >> $GITHUB_OUTPUT python_stuff: runs-on: ubuntu-latest needs: - versions if: inputs.python_enabled == 'true' strategy: matrix: python-version: ${{ fromJSON(needs.versions.outputs.python_versions) }} steps: - run: echo "doing stuff with ${{ matrix.python-version }}" ``` ### Relevant log output ```sh DEBU[0000] evaluating expression '${{ fromJSON(needs.versions.outputs.python_versions) }}' DEBU[0000] expression '${{ fromJSON(needs.versions.outputs.python_versions) }}' evaluated to '%!t(<nil>)' ERRO[0000] Error while evaluating matrix: Cannot parse non-string type invalid as JSON DEBU[0000] FATA[0000] yaml: unmarshal errors: line 19: cannot unmarshal !!str `${{ fro...` into []interface {} ``` ### Additional information Here is a link to github run: https://github.com/20k-ultra/action-tester/actions/runs/3580010001
Author
Owner

@20k-ultra commented on GitHub (Nov 29, 2022):

By the way, if I set if: false for the step I want to skip, this error is still thrown so I don't think I can add any expression to try and work around this.

<!-- gh-comment-id:1331445988 --> @20k-ultra commented on GitHub (Nov 29, 2022): By the way, if I set `if: false` for the step I want to skip, this error is still thrown so I don't think I can add any expression to try and work around this.
Author
Owner

@20k-ultra commented on GitHub (Nov 29, 2022):

Maybe there's a way I can do something like this if it exists (just tested and it doesn't work but maybe there's a correct way to do this)

      python: ${{ steps.python_versions.outputs.json }} || "[]"
<!-- gh-comment-id:1331450545 --> @20k-ultra commented on GitHub (Nov 29, 2022): Maybe there's a way I can do something like this if it exists (just tested and it doesn't work but maybe there's a correct way to do this) ``` python: ${{ steps.python_versions.outputs.json }} || "[]" ```
Author
Owner

@github-actions[bot] commented on GitHub (Jan 29, 2023):

Issue is stale and will be closed in 14 days unless there is new activity

<!-- gh-comment-id:1407517605 --> @github-actions[bot] commented on GitHub (Jan 29, 2023): Issue is stale and will be closed in 14 days unless there is new activity
Author
Owner

@github-actions[bot] commented on GitHub (Jul 29, 2023):

Issue is stale and will be closed in 14 days unless there is new activity

<!-- gh-comment-id:1656478960 --> @github-actions[bot] commented on GitHub (Jul 29, 2023): Issue is stale and will be closed in 14 days unless there is new activity
Author
Owner

@vfilenga commented on GitHub (Aug 18, 2023):

I am finding this same bug at this exact moment

EDIT:

Just so you know, I worked around this by always passing at least an empty array "[]" to the matrix job, and also doing a multi-statement if check to make sure the array is not empty, because it was running the matrix job even with an empty array LOL

<!-- gh-comment-id:1683217839 --> @vfilenga commented on GitHub (Aug 18, 2023): I am finding this same bug at this exact moment EDIT: Just so you know, I worked around this by always passing at least an empty array "[]" to the matrix job, and also doing a multi-statement if check to make sure the array is not empty, because it was running the matrix job even with an empty array LOL
Author
Owner

@ChristopherHX commented on GitHub (Aug 22, 2023):

it was running the matrix job even with an empty array LOL

That's in parity with GitHub Actions (Part of undocumented behavior).

BTW I'm not affected by this problem due to how I use act, so it doesn't gain much attention from my side

<!-- gh-comment-id:1688113188 --> @ChristopherHX commented on GitHub (Aug 22, 2023): > it was running the matrix job even with an empty array LOL That's in parity with GitHub Actions (Part of undocumented behavior). _BTW I'm not affected by this problem due to how I use act, so it doesn't gain much attention from my side_
Author
Owner

@bonzofenix commented on GitHub (Jan 14, 2024):

I found this same issue when I tried to generate the input for the matrix in a dependent job of the main one.

<!-- gh-comment-id:1891035920 --> @bonzofenix commented on GitHub (Jan 14, 2024): I found this same issue when I tried to generate the input for the matrix in a dependent job of the main one.
Author
Owner

@jsoref commented on GitHub (Nov 12, 2024):

Fwiw, I tripped on what I assume is this this w/ powerdns/pdns w/ act version 0.2.69 when running act -l : github.com/PowerDNS/pdns@4b81e7f615/.github/workflows/build-and-test-all.yml (L367-L447)

Error: workflow is not valid. 'build-and-test-all.yml': yaml: unmarshal errors:
  line 446: cannot unmarshal !!str `${{ mat...` into map[string]string
  line 447: cannot unmarshal !!str `${{ mat...` into []string
<!-- gh-comment-id:2470588698 --> @jsoref commented on GitHub (Nov 12, 2024): Fwiw, I tripped on what I assume is this this w/ powerdns/pdns w/ `act version 0.2.69` when running `act -l` : https://github.com/PowerDNS/pdns/blob/4b81e7f615fbe0bb0c65c2811716726ce0228d70/.github/workflows/build-and-test-all.yml#L367-L447 ``` Error: workflow is not valid. 'build-and-test-all.yml': yaml: unmarshal errors: line 446: cannot unmarshal !!str `${{ mat...` into map[string]string line 447: cannot unmarshal !!str `${{ mat...` into []string ```
Author
Owner

@ChristopherHX commented on GitHub (Nov 12, 2024):

@jsoref

when running act -l :

This would be a different issue due to beeing before running anything, please create a new one.

In this case is act's internal workflow model invalid, yes it is invalid to some extend.

It doesn't even has to do with matrix, act doesn't support expression lists for ports and expression mapping for env.

<!-- gh-comment-id:2471570723 --> @ChristopherHX commented on GitHub (Nov 12, 2024): @jsoref > when running `act -l` : This would be a different issue due to beeing **before** running anything, please create a new one. In this case is act's internal workflow model invalid, yes it is invalid to some extend. It doesn't even has to do with matrix, act doesn't support expression lists for ports and expression mapping for env.
Author
Owner

@Andrej730 commented on GitHub (Oct 28, 2025):

I believe I also came across this - matrix expression is still was evaluated, though the job was disabled with if.

Example workflow:

# yest.yml
name: Test Matrix from JSON

on: workflow_dispatch

jobs:
  define_versions:
    runs-on: ubuntu-latest
    if: false
    outputs:
      target_versions: ${{ steps.versions.outputs.target_versions }}
    steps:
    - name: Define versions
      id: versions
      run: echo "target_versions=[\"v1\", \"v2\", \"v3\"]" >> $GITHUB_OUTPUT

  use_matrix:
    needs: define_versions
    runs-on: ubuntu-latest
    if: false
    strategy:
      matrix:
        version: ${{ fromJson(needs.define_versions.outputs.target_versions) }}
    steps:
    - run: echo ${{ matrix.version }}

  hello_job:
    runs-on: ubuntu-latest
    steps:
    - run: echo hello

Github actions:

Image

act:

$ act
INFO[0000] Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'
[Test Matrix from JSON/hello_job      ] ⭐ Run Set up job
[Test Matrix from JSON/hello_job      ] 🚀  Start image=catthehacker/ubuntu:act-24.04
[Test Matrix from JSON/hello_job      ]   🐳  docker pull image=catthehacker/ubuntu:act-24.04 platform= username= forcePull=true
[Test Matrix from JSON/hello_job      ]   🐳  docker create image=catthehacker/ubuntu:act-24.04 platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Test Matrix from JSON/hello_job      ]   🐳  docker run image=catthehacker/ubuntu:act-24.04 platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Test Matrix from JSON/hello_job      ]   🐳  docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[Test Matrix from JSON/hello_job      ]   ✅  Success - Set up job
[Test Matrix from JSON/hello_job      ] ⭐ Run Main echo hello
[Test Matrix from JSON/hello_job      ]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
| hello
[Test Matrix from JSON/hello_job      ]   ✅  Success - Main echo hello [115.341674ms]
[Test Matrix from JSON/hello_job      ] ⭐ Run Complete job
[Test Matrix from JSON/hello_job      ] Cleaning up container for job hello_job
[Test Matrix from JSON/hello_job      ]   ✅  Success - Complete job
[Test Matrix from JSON/hello_job      ] 🏁  Job succeeded
ERRO[0001] Error while evaluating matrix: Invalid JSON: invalid character '$' looking for beginning of value
FATA[0001] Failed to decode node {4 0 !!map   <nil> [0xc0004519a0 0xc000451a40]    22 9} into *map[string][]interface {}: yaml: unmarshal errors:
  line 22: cannot unmarshal !!str `${{ fro...` into []interface {}
<!-- gh-comment-id:3457339676 --> @Andrej730 commented on GitHub (Oct 28, 2025): I believe I also came across this - `matrix` expression is still was evaluated, though the job was disabled with `if`. Example workflow: ```yml # yest.yml name: Test Matrix from JSON on: workflow_dispatch jobs: define_versions: runs-on: ubuntu-latest if: false outputs: target_versions: ${{ steps.versions.outputs.target_versions }} steps: - name: Define versions id: versions run: echo "target_versions=[\"v1\", \"v2\", \"v3\"]" >> $GITHUB_OUTPUT use_matrix: needs: define_versions runs-on: ubuntu-latest if: false strategy: matrix: version: ${{ fromJson(needs.define_versions.outputs.target_versions) }} steps: - run: echo ${{ matrix.version }} hello_job: runs-on: ubuntu-latest steps: - run: echo hello ``` Github actions: <img width="710" height="345" alt="Image" src="https://github.com/user-attachments/assets/40995a4e-7ca4-4fa4-92ce-0d2e0cf656dd" /> `act`: ```sh $ act INFO[0000] Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock' [Test Matrix from JSON/hello_job ] ⭐ Run Set up job [Test Matrix from JSON/hello_job ] 🚀 Start image=catthehacker/ubuntu:act-24.04 [Test Matrix from JSON/hello_job ] 🐳 docker pull image=catthehacker/ubuntu:act-24.04 platform= username= forcePull=true [Test Matrix from JSON/hello_job ] 🐳 docker create image=catthehacker/ubuntu:act-24.04 platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host" [Test Matrix from JSON/hello_job ] 🐳 docker run image=catthehacker/ubuntu:act-24.04 platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host" [Test Matrix from JSON/hello_job ] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir= [Test Matrix from JSON/hello_job ] ✅ Success - Set up job [Test Matrix from JSON/hello_job ] ⭐ Run Main echo hello [Test Matrix from JSON/hello_job ] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir= | hello [Test Matrix from JSON/hello_job ] ✅ Success - Main echo hello [115.341674ms] [Test Matrix from JSON/hello_job ] ⭐ Run Complete job [Test Matrix from JSON/hello_job ] Cleaning up container for job hello_job [Test Matrix from JSON/hello_job ] ✅ Success - Complete job [Test Matrix from JSON/hello_job ] 🏁 Job succeeded ERRO[0001] Error while evaluating matrix: Invalid JSON: invalid character '$' looking for beginning of value FATA[0001] Failed to decode node {4 0 !!map <nil> [0xc0004519a0 0xc000451a40] 22 9} into *map[string][]interface {}: yaml: unmarshal errors: line 22: cannot unmarshal !!str `${{ fro...` into []interface {} ```
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#760
No description provided.