Unrecognized named-value: 'matrix' in job if conditional
Describe the bug
A job generates a matrix as an output and I have a subsequent job that depends on the generation of that matrix. The first job does an API call to get all customers which each have a unique schema association. I only want to run this second job in the event that my input SCHEMA array contains the schema of a given return record. However, when I execute the build I get the following error: Unrecognized named-value: 'matrix'. Located at position 26 within expression: contains(inputs.SCHEMAS, matrix.customer.schema). The pattern works without the conditional, but does not fit my use case.
This is a rough idea of what the job looks like.
job-name:
runs-on: ubuntu-latest
needs: get-customers
if: contains(inputs.SCHEMAS, matrix.customer.schema)
strategy:
matrix:
customer: ${{fromJson(needs.get-customers.outputs.customers)}}
steps:
....
Expected behavior The job should only run when the matrix schema is contained within the input SCHEMA
Runner Version and Platform
ubuntu-latest
What's not working?
The use of matrix in a job level conditional
I had the same issue, it seems that if statement is evaluated before running a matrix of jobs. I found this topic on GitHub forum about this problem.
I do have the same issue, and not using any if statement. And the matrix value does not contain any spaces.
list-dev-configs:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v3
- id: set-matrix
run: echo "::set-output name=matrix::[\"A\",\"B\"]"
check:
needs: list-dev-configs
runs-on: ubuntu-latest
strategy:
matrix:
dev_config: ${{ fromJSON(needs.list-dev-configs.outputs.matrix) }}
steps:
- uses: actions/checkout@v3
- run: |
echo "${{ needs.list-dev-configs.outputs.matrix }}"
echo "${{ fromJSON(needs.list-dev-configs.outputs.matrix) }}"
echo "${{ martix.dev_config }}"
My bad, that was a typo in the script last line martix instead of matrix.
Also having this issue. the workflow works fine if there was no if statement.
build:
needs: manifest
strategy:
matrix: ${{ fromJson(needs.manifest.outputs.build_matrix) }}
uses: andaman-common-pkgs/github-actions/.github/workflows/anda-rpm.yml@main
if: ${{ matrix.changed_folders != '' }}
with:
name: "rust/${{ matrix.changed_folders }}/pkg"
subatomicServer: "https://subatomic.fyralabs.com"
subatomicRepo: ad37
mockConfig: anda-37-x86_64
mockConfigPackage: anda-mock-configs
upload: true
secrets:
subatomicToken: ${{ secrets.SUBATOMIC_TOKEN }}
I also have this problem in https://github.com/Lightning-AI/lightning/pull/15043
You can probably work around this by having additional jobs that generate outputs and relying on needs and the outputs from those jobs.
You might need to demote your ifs from job level to step level.
Same problem here. Are there any plans to add the matrix context to the jobs.<job_id>.if condition?
I'm also encountering this issue.
Sadly my workflow had to be changed from this:
jobs:
remediate:
runs-on: ubuntu-latest
strategy:
matrix:
env: ["dev", "test", "prod"]
if: ${{ github.event.schedule || matrix.env == github.event.inputs.env }}
environment: ${{ matrix.env }}
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: cue-lang/[email protected]
with:
[ etc... ]
to this:
jobs:
remediate:
runs-on: ubuntu-latest
strategy:
matrix:
env: ["dev", "test", "prod"]
environment: ${{ matrix.env }}
steps:
- name: Checkout
if: ${{ github.event.schedule || matrix.env == github.event.inputs.env }}
uses: actions/checkout@v2
- uses: cue-lang/[email protected]
if: ${{ github.event.schedule || matrix.env == github.event.inputs.env }}
with:
[ etc... ]
Obviously with a few more steps than in the above truncated example.
It makes the whole workflow feel a bit messy, especially since the jobs are being marked as successfully run when in reality all the steps within it have been skipped.
(never mind my failed job, it's still in development😅)

@mrkesu: if you're up for it, you should really try having a job that creates your matrix and then have it create an empty array when you don't want it to do work. https://github.com/actions/runner/issues/1985#issuecomment-1275812256
Here's a workflow which does something similar: https://github.com/commercialhaskell/stack/blob/71a85a488ef458d5c7d315b647411056aafd3d0a/.github/workflows/integration-tests.yml#L104-L127
I ran into this issue today as well. Can the matrix context indeed be added to jobs.<job_id>.if ? I would imagine that if it is available for runs-on, it should be possible to make it available for jobs.<job_id>.if too, as I would expect both are evaluated before starting the job.
My use case is in reusable workflows, where I also want to reuse my matrix for several projects, However, there are projects who don't need all configurations. So I want to allow the calling workflow to use input parameters to skip certain matrix entries. For example, I would very much like something like this to work, which would allow the calling workflow to control whether to build for win32:
on:
workflow_call:
inputs:
build-win32:
required: true
type: boolean
jobs:
build:
strategy:
matrix:
include:
- os: windows-latest
arch: "win64"
build: true
- os: windows-latest
arch: "win32"
build: ${{ inputs.build-win32 }}
- os: ubuntu-latest
build: true
if: ${{ matrix.build }}
runs-on: ${{ matrix.os }}
I've seen workarounds that use a separate job to set up a matrix, but that solution is (1) much harder to understand than this one, and (2) will introduce an extra job in your output that is just noise.
It's indeed a bit surprising to get this error when seeing that runs-on works just fine with it:
runs-on: ${{ matrix.os }} # ok
if: ${{ matrix.os == 'ubuntu-latest' }} # not ok
Here is the most elegant solution I found to this issue:
jobs:
exclude-jobs:
runs-on: ubuntu-latest
outputs:
jobs: ${{ steps.exclude-jobs.outputs.jobs }}
steps:
- id: exclude-jobs
# 1. use any other condition(s) that fits your requirements
# 2. each item in the JSON array will be matched against your matrix later
# 3. here I exclude everything except ubuntu-latest + python3.7 (see matrix below)
# 4. make sure to output as single line
# 5. the default case is: exclude nothing
run: |
if ${{ github.repository_owner == 'pawamoy-insiders' }}; then # 1
# 2, 3
echo 'jobs=[
{"os": "macos-latest"},
{"os": "windows-latest"},
{"python-version": "3.8"},
{"python-version": "3.9"},
{"python-version": "3.10"},
{"python-version": "3.11"}
]' | tr -d '[:space:]' >> $GITHUB_OUTPUT # 4
else
echo 'jobs=[]' >> $GITHUB_OUTPUT # 5
fi
tests:
needs: exclude-jobs
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
python-version:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
# simply use the previous JSON data you echoed to exclude jobs
exclude: ${{ fromJSON(needs.exclude-jobs.outputs.jobs) }}
Thanks @pawamoy that worked for me, in order to use a one dimensional set of inputs and rather use include:
jobs:
include-jobs:
runs-on: ubuntu-latest
outputs:
jobs: ${{ steps.include-jobs.outputs.jobs }}
steps:
- id: include-jobs
run: |
includeJobs='
${{ inputs.enable_web && '{"platform": "web", "os": "ubuntu-latest", "build-type": "web"},' || '' }}
${{ inputs.enable_android && '{"platform": "android", "os": "ubuntu-latest", "build-type": "apk"},' || '' }}
${{ inputs.enable_ios && '{"platform": "ios", "os": "macos-latest", "build-type": "ipa"},' || '' }}
'
# Remove last ',' with ::-1
echo "jobs=[${includeJobs::-1}]" | tr -d '[:space:]' >> $GITHUB_OUTPUT
build-client:
needs: include-jobs
runs-on: ${{ matrix.os }}
strategy:
matrix:
include: ${{ fromJSON(needs.include-jobs.outputs.jobs) }}
@pawamoy @Gustl22 You can also do it this way:
jobs:
ReuseableMatrixJobForDeployment:
strategy:
matrix:
target: [dev, stage, prod]
uses: ./.github/workflows/base.yml
with:
target: ${{ matrix.target }}
Inside nested job if will work again.
https://docs.github.com/en/actions/using-workflows/reusing-workflows#using-a-matrix-strategy-with-a-reusable-workflow
I just ran into this issue. As others pointed out, it seems unintuitive that runs-on can access the matrix but if can't. Both proposed workarounds (moving ifs to steps or creating a new job to make the matrix) add a lot of unneeded complexity.
Any chance we could see this be added?
The 3rd example in the Repo should be useful in conditionally build the matrix in the GitHub Actions. https://github.com/dorny/paths-filter?tab=readme-ov-file#examples