Azure Pipelines Condition Always Skips a Job or Stage
A custom condition: replaces the implicit succeeded(). If you write a condition without including succeeded()/and(), or compare values of the wrong type, the job or stage is skipped (or runs when it should not).
What this error means
A job or stage with a custom condition is skipped even though upstream work passed, or it runs after a failure. The condition expression is silently evaluating to false (or true) for a reason that is easy to miss.
# wrong: drops the implicit success check, so it runs even after failure
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
# also wrong: compares a string to a boolean
condition: eq(variables.isPr, true) # variables are strings -> use 'True'Common causes
Custom condition drops succeeded()
Adding any condition: overrides the default succeeded(). Without and(succeeded(), ...) the stage may run after an upstream failure, or your boolean logic alone evaluates false and it skips.
Type mismatch in eq()
Pipeline variables are strings. eq(variables.x, true) compares a string to a boolean and is false; you need eq(variables.x, 'True') (note the string and casing).
How to fix it
Combine succeeded() with your check
Wrap the custom logic in and(succeeded(), ...) so the success gate is preserved.
jobs:
- job: deploy
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))Compare against string values
Treat variables as strings in eq(), matching value and case.
condition: and(succeeded(), eq(variables['System.PullRequest.IsFork'], 'False'))How to prevent it
- Always include
succeeded()in a custom condition unless you intend otherwise. - Treat variables as strings (
'True'/'False') in comparisons. - Use
dependencies/stageDependenciesoutputs explicitly in conditions.