Skip to content
Latchkey

Azure Pipelines "A template expression is not allowed in this context"

You used a compile-time template expression ${{ }} somewhere the schema only allows a literal or a runtime expression. Azure has three expression syntaxes and they are not interchangeable.

What this error means

The pipeline fails to compile with A template expression is not allowed in this context, pointing at a ${{ ... }} you placed in a field that is evaluated later, at runtime.

Azure DevOps
/azure-pipelines.yml (Line: 20, Col: 18): A template expression is not
allowed in this context

Diagnose it: variables, expressions, or the agent?

Azure Pipelines resolves compile-time expressions (${{ }}) before the run and runtime expressions ($[ ]) during it. Using the wrong one is the most common source of a value that is empty when you read it.

azure-pipelines.yml
# print what the job actually resolved
- script: |
    echo "reason: $(Build.Reason)"
    echo "branch: $(Build.SourceBranch)"
    env | sort | head -40
  displayName: Dump context

# enable full diagnostics on a run: set system.debug = true as a variable

Common causes

Compile-time syntax in a runtime-only field

Template expressions ${{ }} are expanded before the run starts. Fields that depend on runtime state (like a step condition referencing a prior job result) must use runtime $[ ] or macro $( ) syntax instead.

Mixing the three expression types

Azure has ${{ }} (template, compile time), $[ ] (runtime expression), and $( ) (macro). Using the wrong one for the context - e.g. ${{ }} to read an output variable set during the run - is rejected.

How to fix it

Use a runtime expression for runtime values

When the value is only known during the run (output vars, conditions on prior steps), switch to $[ ].

azure-pipelines.yml
variables:
  isMain: $[ eq(variables['Build.SourceBranch'], 'refs/heads/main') ]

Reserve template expressions for parameters

  1. Use ${{ }} for parameters.*, conditional insertion, and loops - all resolved before the run.
  2. Use $( ) to substitute a variable into a script or argument string.
  3. Use $[ ] for variable definitions and conditions that depend on runtime results.

How to prevent it

  • Learn the three expression syntaxes and where each is legal.
  • Keep parameter logic in ${{ }} and runtime logic in $[ ].
  • Validate templates in the pipeline editor before merging.

Frequently asked questions

What causes Azure Pipelines "A template expression is not allowed in this context"?
There are 2 common causes: compile-time syntax in a runtime-only field and mixing the three expression types. Template expressions ${{ }} are expanded before the run starts.
How do I fix Azure Pipelines "A template expression is not allowed in this context"?
There are 2 fixes depending on which cause you have: use a runtime expression for runtime values and reserve template expressions for parameters. Work through them in order, since the first is the most common.
What does Azure Pipelines "A template expression is not allowed in this context" actually mean?
The pipeline fails to compile with A template expression is not allowed in this context, pointing at a ${{ ...
How do I stop Azure Pipelines "A template expression is not allowed in this context" happening again?
Learn the three expression syntaxes and where each is legal. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card