Skip to content
Latchkey

Scheduled matrix build context and runner availability in CI

A matrix works the same under schedule as under push, expanding one job per combination. The gotchas are that it runs on the default branch, needs runner capacity for every leg, and cannot read PR-only context.

What this error means

A scheduled matrix runs fewer legs than expected, queues waiting for runners, or a leg fails because it read context (like head_ref) that is empty under a schedule.

.github/workflows/nightly.yml
strategy:
  matrix:
    python: ['3.10', '3.11', '3.12']
# On schedule, all 3 legs queue on the default branch and
# compete for runner capacity at the same cron slot.

Common causes

All legs queue at once for runners

Every matrix combination requests a runner at the same cron slot, so limited capacity delays or queues legs.

Default-branch context under schedule

The matrix runs on the default branch, so any PR-specific context is unavailable to the legs.

How to fix it

Bound parallelism and ensure capacity

  1. Set max-parallel to fit available runner capacity.
  2. Keep matrix legs independent and idempotent.
  3. Do not depend on PR-only context inside legs.
.github/workflows/nightly.yml
strategy:
  max-parallel: 2
  matrix:
    python: ['3.10', '3.11', '3.12']

Reduce the nightly matrix if capacity is tight

Run the full matrix on push and a smaller representative matrix on the schedule to avoid queueing.

How to prevent it

  • Size the scheduled matrix to your runner capacity.
  • Use max-parallel to avoid runner starvation.
  • Avoid PR-only context in scheduled matrix legs.

Frequently asked questions

What causes "matrix under a schedule"?
Every matrix combination requests a runner at the same cron slot, so limited capacity delays or queues legs.
How do I fix matrix under a schedule?
Bound parallelism and ensure capacity

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card