I set up a scheduled pipeline in Azure DevOps. The YAML was valid. No errors on save. I waited patiently for the cron to fire.
Nothing happened…
The culprit turned out to be a single line I'd added for a completely legitimate reason trigger: none.
The setup
The pipeline looked roughly like this:
trigger: none
schedules:
- cron: "0 2 * * 1-5"
displayName: Nightly weekday build
branches:
include:
- main
always: true
The intent was straightforward: I didn't want CI runs on every push, so I explicitly disabled that with trigger: none. And I wanted the pipeline to run on a schedule. Seems fine, right?
Except it never ran.
What's actually happening
Here's the thing that isn't obvious until you read the docs carefully (or waste an afternoon debugging): in Azure DevOps YAML pipelines, trigger is specifically the CI trigger — the thing that fires on code pushes. schedules is a completely separate concept.
So when I wrote trigger: none, I was trying to tell Azure DevOps: "don't fire on commits." That's it. I expected schedules to happily do its own thing in parallel.
But it didn’t.
When trigger: none is present, Azure DevOps suppresses scheduled runs as well. The schedule is defined, it validates fine, it even shows up if you look at the pipeline configuration — but the runs simply don't happen.
There's no warning. No error. No notification. Just silence.
The fix
Remove trigger: none. That's it.
If you don't want CI triggers firing on every push, but you do want scheduled runs, the correct approach is to either:
Option A — Let the default CI trigger stand, but scope it narrowly:
trigger:
branches:
include:
- none # effectively disables CI without using trigger: none
schedules:
- cron: "0 2 * * 1-5"
displayName: Nightly weekday build
branches:
include:
- main
always: true
Option B — Just remove trigger: entirely if this is a schedule-only pipeline:
schedules:
- cron: "0 2 * * 1-5"
displayName: Nightly weekday build
branches:
include:
- main
always: true
Without an explicit trigger: section, Azure DevOps applies the default CI behavior (trigger on all branches), unless your organization has the "Disable implied YAML CI trigger" setting enabled at org or project level. If you're worried about that, scope the CI trigger explicitly to a non-existent branch, or check your org settings.
Why I find this confusing?
Because the mental model I had is: "these are independent trigger types, and I can configure them independently." That's true in many CI systems. In Azure DevOps YAML, trigger: none is a broader hammer than it looks.
The official documentation does document this, but it's easy to miss if you're just looking to disable CI triggers and move on.
Other gotchas while we are here
If your scheduled pipeline still isn't running after removing trigger: none, check these:
UI-defined schedules override YAML schedules. If you ever configured a schedule through the pipeline settings UI, that takes precedence over everything you define in YAML. Only UI-defined schedules will run, and you'll need to delete them through the UI (then trigger a new push) before your YAML schedules take effect.
The schedule is evaluated per branch. A schedule only applies to branches explicitly listed in the branches.include section. If you're targeting main but your YAML changes are on a feature branch, the schedule for main is based on the last committed YAML on main. Changes on other branches don't update the schedule for main.
always: true matters. By default, Azure DevOps won't run a scheduled build if there have been no code changes since the last successful run. Set always: true if you want the pipeline to run regardless.
Verify with Scheduled Runs view. In the Azure DevOps UI, go to your pipeline and select "Scheduled runs" from the ... menu. This shows you the next few upcoming runs. If nothing shows there, your schedule isn't being picked up — regardless of what's in your YAML.
TL;DR
trigger: none doesn't just disable CI triggers — it disables scheduled runs too. If you want a schedule-only pipeline, remove the trigger: key entirely, or scope the CI trigger to something that won't match.
One line. No validation error. Hours of head-scratching.
More information
Triggers in Azure Pipelines - Azure Pipelines | Microsoft Learn
