Another confusing Azure DevOps Pipelines YAML error message using StringList parameters

Introduction

The recent addition to Azure DevOps of the StringList parameter type can be really useful to dynamically create parallel stages or jobs in an Azure DevOps YAML pipeline.

A StringList parameter can be used to present a list of values to the user queuing a pipeline run, thus allowing the selection of one or more values that can be accessed using a YAML expression loop.

This can be combined with YAML templates, where the StringList is passed into a template as an Object. Noting that you can’t use the StringList type for a parameter type in the template definition. However, this is not a problem as there is a dynamic conversion from StringList to Object e.g.

# Azure-Pipeline.yml
parameters:
  - name: environments
    type: stringList
    default: 
      - dev
    values:
      - dev
      - test
      - prod

trigger: none

extends:
  template: template.yml
  parameters:
    environments: ${{parameters.environments }}
# template.yml
parameters:
  - name: environments
    type: object

stages:
  - stage: Deploy
    pool:
      vmImage: ubuntu-latest
    jobs:
      - job: DeployJob
        steps:
          - checkout: none
          - ${{ each value in parameters.environments }}:
            - script: |
                echo "Selected environments: ${{ value }}"

The Problem

Whilst implementing this new parameter type on an existing pipeline we got a very strange set of error messages ‘Unexpected a mapping’, ‘Unexpected at least one-value pair in the mapping’ and ‘Unexpected state while attempting t read the mapping end state’

StringList Error

After much experimentation we found the issue was the indenting of a steps block later in the YAML. When the new loop expression was added only part of the jobs block was correctly indented.

The indenting was

  jobs:
  - ${{ each environment in parameters.Environments }}:
    - job: build_${{ environment }}
    steps:
      ...

When it should have been

  jobs:
  - ${{ each environment in parameters.Environments }}:
    - job: build_${{ environment }}
      steps:
        ...

So as usual when you get an unexpected and unclear error in Azure DevOps YAML, assume the problem is due to whitespace.

For the original version of this post see Richard Fennell's personal blog at Another confusing Azure DevOps Pipelines YAML error message using StringList parameters