runner: Setting strategy.matrix.value to expression throws invalid type error

Getting “Invalid type found: array was expected but string was found” at matrix: value: ${{fromJson(needs.setup.outputs.matrix)}}

Any ${{}} expression fails. Only [] is allowed now, with at least one value. But the value cannot be an expression.

`name: Test Matrix

on: workflow_dispatch:

jobs:

setup: runs-on: ubuntu-latest outputs: matrix: ${{ steps.matrix.outputs.value }} steps: - id: matrix run: | echo ‘::set-output name=value::["a", "b", "c"]’ build: needs: [ setup ] runs-on: ubuntu-latest strategy: matrix: value: ${{fromJson(needs.setup.outputs.matrix)}} steps: - run: | echo “${{ matrix.value }}”`

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 7
  • Comments: 32 (7 by maintainers)

Most upvoted comments

This was driving me crazy, originally I was using cat and jq together to get the content into a string: cat releases.json | jq 'tostring' and then adding it to the GITHUB_OUTPUT:

echo "matrix=$(cat releases.json | jq 'tostring')" >> $GITHUB_OUTPUT

but when I ran the workflow I always got this error:

Unexpected type of value '[{"name":"XXX","ip_address":"XXX"},{"name":"XXX","ip_address":"XXX"}]', expected type: Sequence.

Note: I’ve been using the include property when defining the matrix.

Anyways, for some reason a pair of single quotes were added even removing with sed threw another error message:

Error parsing fromJson,.github/workflows/XXX.yaml (Line: 164, Col: 18): Invalid property identifier character: \. Path '[0]', line 1, position 2.,.github/workflows/XXX.yaml (Line: 164, Col: 18): Unexpected type of value '', expected type: Sequence.

The solution that I found was to use a multiline string, e.g.:

    steps:
      - name: Get JSON content
        id: get-json-content
        run: |
          echo 'JSON_CONTENT<<EOF' >> $GITHUB_OUTPUT
          cat releases.json >> $GITHUB_OUTPUT
          echo 'EOF' >> $GITHUB_OUTPUT
    outputs:
      new_content: ${{ steps.get-json-content.outputs.JSON_CONTENT }} 

Job using matrix:

  matrix_job_test:
    name: Matrix job test
    runs-on: ubuntu-latest
    needs: test_job
    strategy:
      matrix:
        include: ${{ fromJSON(needs.test_job.outputs.new_content) }}
    steps:
      - run: |
          echo $STACK_NAME
          echo $STACK_IP
        env:
          STACK_NAME: ${{ matrix.name }}
          STACK_IP: ${{ matrix.ip_address }}

In case someone wonder, this is the JSON content structure:

[
  {
  "name": "string",
  "ip_address": "string"
  },
  {
    "name": "string",
    "ip_address": "string"
  }
]

I hope this helps other people, cheers!

Is there any intention to fix this or make the documentation on it intuitive at all?

I don’t even see how this got into general availability. It’s clearly barely been tested

hi,

seems to be a bug and it did fail until I rewrote every line manually with all the correct indentations and spaces
also i found out that if you copy-paste it from somewhere it does not run seems to me that there are hidden chars while copypasting

i ignored the error ‘invalid type found: array was expected but string was found’ and continued it might a case of incorrect indentations and spaces , not sure, if so its a bug for sure.

still error should not appear while editing

my account.txt file is:

1111111 2222222

jobs:
  list-manifests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - id: set-matrix
        run: echo "::set-output name=matrix::$(cat accounts.txt | jq -R -s -c 'split("\n")[:-1]')"
    outputs:
       matrix: ${{ steps.set-matrix.outputs.matrix }}
  

  check:
    needs: [list-manifests]
    runs-on: ubuntu-latest
    strategy:
      matrix: 
        manifest: ${{ fromJson(needs.list-manifests.outputs.matrix) }}
    steps:
      - name: test
        run: |
          echo ${{ matrix.manifest }}
        shell: bash

@nikola-jokic thanks for the fast responses. I hope someone finds these posts after spending some time searching and trial and error and figures out fromJSON is the key! thanks!

Hi @ag-monk,

Could you please provide an example of your workflow file so I can take a look? While investigating this, I used workflow file:

name: build
on: push
jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.value }}
    steps:
      - id: set-matrix
        run: echo "::set-output name=value::['a','b','c']"
  job2:
    needs: job1
    runs-on: ubuntu-latest
    strategy:
      matrix:
        value: ${{fromJSON(needs.job1.outputs.matrix)}}
    steps:
      - run: echo "${{ matrix.value }}"

Also, please keep in mind this example: https://docs.github.com/en/actions/learn-github-actions/expressions#example-returning-a-json-object.

Both of them worked so there might be some issues within your definition that are causing this syntax error.

I’m having the same issue.

Error when evaluating ‘strategy’ for job ‘disable-replication’. .github/workflows/deploy.yml : Error parsing fromJson,.github/workflows/deploy.yml : Error reading JToken from JsonReader. Path ‘’, line 0, position 0.,.github/workflows/deploy.yml : Unexpected type of value ‘’, expected type: Sequence.

disable-replication:
  runs-on: ubuntu-latest
  strategy:
    matrix:
      server: ${{ fromJson(vars.SERVERS_JSON) }}
  steps:
    - name: Hello world
      run: echo ${{ matrix.server.name }}
My SERVERS_JSON variable looks like this:
[
  {
    "name": "backend",
    "host": "backend.example.com",
    "user": "www-example"
  },
  {
    "name": "frontend-a",
    "host": "frontend-a.example.com",
    "user": "www-example"
  },
  {
    "name": "frontend-b",
    "host": "frontend-b.example.com",
    "user": "www-example"
  }
]

I also tried to change it to a oneliner JSON:

[{"name":"backend","host":"backend.example.com","user":"www-example"},{"name":"frontend-a","host":"frontend-a.example.com","user":"www-example"},{"name":"frontend-b","host":"frontend-b.example.com","user":"www-example"}]

But that did not resolve it either.


When I change my job to inline the array, everything works fine.

Inlined working example
disable-replication:
  runs-on: ubuntu-latest
  strategy:
    matrix:
      server: [
        {
          "name": "backend",
          "host": "backend.example.com",
          "user": "www-example"
        },
        {
          "name": "frontend-a",
          "host": "frontend-a.example.com",
          "user": "www-example"
        },
        {
          "name": "frontend-b",
          "host": "frontend-b.example.com",
          "user": "www-example"
        }
      ]
  steps:
    - name: Hello world
      run: echo ${{ matrix.server.name }}

Workaround

It seems the workaround mentioned by javierlga works. When you create the matrix json in another job, things work fine.

+create-server-matrix:
+  runs-on: ubuntu-latest
+  outputs:
+    server-matrix: ${{ steps.create-server-matrix.outputs.SERVER_MATRIX }}
+  container: debian:bullseye-slim
+  steps:
+    - name: Install jq
+      run: apt-get update -y && apt-get install -y jq
+
+    - name: Create server matrix
+      id: create-server-matrix
+      env:
+        SERVERS_JSON: ${{ vars.SERVERS_JSON }}
+      run: echo "SERVER_MATRIX=$(echo "$SERVERS_JSON" | jq -r 'tostring')" >> $GITHUB_OUTPUT

disable-replication:
  runs-on: ubuntu-latest
+ needs: [ create-server-matrix ]
  strategy:
    matrix:
-     server: ${{ fromJson(vars.SERVERS_JSON) }}
+     server: ${{ fromJson(needs.create-server-matrix.outputs.server-matrix) }}
  steps:
    - name: Hello world
      run: echo ${{ matrix.server.name }}

For sure, you are completely right. Because of it, you should always use fromJSON. We have a similar situation with declaring booleans in inputs. They will be treated as strings, so fromJSON is there to help you parse it to the data type which will be accepted.

I had this problem because I was escaping the quotes as it said in a lot of posts, but removing that fixed my issue.

Took me a bit, but got this working (relevant snippets):

Constructing an array in one job (files here is a newline separated list of files):

    outputs:
      job_files_changed_array: ${{ steps.job_files_changed.outputs.files }}

          fmt="$(echo -n "${files}" | paste -sd ',' - | sed -e 's/,/", "/g')"
          echo 'files=["'"${fmt}"'"]' >> "$GITHUB_OUTPUT"

Using the array in another:

    strategy:
      matrix:
        value: ${{ fromJson(needs.changed.outputs.job_files_changed_array) }}

I have been looking around for this issue for a couple of days now. This works but have to use this bodge as workaround. Thanks so much javierlga Javier Lizarraga

Hi @nikola-jokic i also hit this problem and all examples in this issue like you mention in comment or from doc fail with error Invalid type found: array was expected but string was found

can you reopen this issue thanks

Yes I am also facing the same problem as [ashish-raj-wenovate] faced.

I am trying the exact sample on the doc here but looks like it matrix is not picking up the json abject.

image

Yeah, its the nested bracket I think. There is probably a better way to do it but the way I handle it right now is generate a map in a flat plane and repeat it within the matrix. I cannot remember if its a listed set of maps or just straight maps. so either: [{“Name” : “Jeff”, “Age”: “109”}, {“Name”: “John”, “Age”: “42”}] or just {“Name” : “Jeff”, “Age”: “109”}, {“Name”: “John”, “Age”: “42”}. This would run two instances of Job2 both with access with the matrixed data. If you want a better example shoot me a contact.

Hello @nikola-jokic Thanks for the response. No matter how I controlled the output, and modified the echo, it’s like actions is wrapping the single quote not the thing producing the output. The only way I found around this was to change the return into Jason and import the matrix from Jason.

Im fighting with this as well. If I change matrix.regions over to the output of my script, it works. If I leave the output of the regions variable from the last job, it errors out. It seems it does not like it when wrapped in single quotes?

[Pre-Setup : .github#L1] Error when evaluating ‘strategy’ for job ‘Deploy-ECR’. (Line: 45, Col: 18): Unexpected value ‘[us-east-1, us-east-2, us-west-2]’

strategy: matrix: regions: ${{ needs.Pre-Setup.outputs.regions }}