didrun · GitHub Actions schedules

Did your scheduled GitHub workflows run when they should have?

$ npx --allow-git=root github:agentwares/didrun

didrun compares what each workflow's on.schedule promised with the runs GitHub actually created, over the last 7 days (up to 30). It lists the runs that came late, the ones that never came, the ones that failed and the green ones that did nothing, and the schedules GitHub has quietly disabled. GitHub sends no alert for any of these.

Run it in a clone, or name the repo. It reads GitHub's own record with your token (GITHUB_TOKEN, GH_TOKEN or the GitHub CLI's login), and with none it reads public repos. Its only requests are GETs to GitHub's API; the token is never printed or stored. No account, no change to your repo. Free and MIT licensed.

Source · a GitHub Action · an MCP tool, didrun_check_schedules, served by didrun mcp

What it prints

$ npx --allow-git=root github:agentwares/didrun demo
Synthetic repo, written for this demo: not anyone's repo or runs.

didrun 0.1.0 · synthetic-org/nightly-jobs · Fri 2 Oct 13:00 UTC to Fri 9 Oct 13:00 UTC (7 days) · recorded synthetic fixtures

4 scheduled workflows: 36 runs due, 34 ran (32 on time, 2 late), 2 missed; 1 failed, 1 green but did
nothing and 1 workflow disabled.

Nightly backup  ·  .github/workflows/backup.yml
  schedule     0 3 * * * (UTC)
  runs due     7: 6 ran, 1 late, 1 missed; 1 failed, 1 did nothing
  missed       Sun 4 Oct 03:00 UTC  no run was created
  did nothing  Mon 5 Oct 03:00 UTC  green in 6 s; its usual success takes 4 min 8 s
  late         Tue 6 Oct 03:00 UTC  the run was created 2 h 17 min late
  failed       Thu 8 Oct 03:00 UTC  the run failed after 1 min 30 s
  last run     Fri 9 Oct 03:04 UTC, success
  next due     Sat 10 Oct 03:00 UTC
  fix          GitHub delays and drops scheduled runs under high load, which includes the start of
               every hour: move the minute off :00 (e.g. 17 instead of 0)
               open the green runs that were short: usually every job or step was skipped by an
               `if:`, or the job found nothing to do and exited 0

Sync prices  ·  .github/workflows/sync.yml
  schedule     0 */6 * * * (UTC)
  runs due     28: 27 ran, 1 late, 1 missed
  missed       Sun 4 Oct 06:00 UTC  no run was created
  late         Wed 7 Oct 18:00 UTC  the run was created 47 min late
  last run     Fri 9 Oct 12:03 UTC, success
  next due     Fri 9 Oct 18:00 UTC
  fix          GitHub delays and drops scheduled runs under high load, which includes the start of
               every hour: move the minute off :00 (e.g. 17 instead of 0)

Close stale issues  ·  .github/workflows/stale.yml
  schedule     0 0 * * * (UTC)
  state        disabled by GitHub: no repository activity in 60 days (public repositories only)
  last run     Sun 9 Aug 00:07 UTC, success (61 days ago)
  fix          gh workflow enable stale.yml -R synthetic-org/nightly-jobs
               then keep the repo active: GitHub disables a public repo's scheduled workflows again
               after 60 days without activity

Weekly report  ·  .github/workflows/report.yml
  schedule     30 8 * * 1 (America/New_York)
  runs due     1: on time
  last run     Mon 5 Oct 12:41 UTC, success (4 days ago)
  next due     Mon 12 Oct 12:30 UTC

Not scheduled: 1 workflow (ci.yml).

This repository is public and its last push was 48 days ago. GitHub disables a public repo's
scheduled workflows after 60 days without activity: around 20 Oct 2026 (in 12 days), unless there is
activity first.

An hourly watch for scheduled runs is not built.
Would you pay for one that emails you when a run is late, missed or did nothing? One click counts:
  https://agentwares-agentcheck.vercel.app/didrun?ref=didrun#watch
Synthetic repo: the real output of npx --allow-git=root github:agentwares/didrun demo, which runs the check on recorded fixtures shipped with it. Not anyone's repo or runs.

What it catches

  • Missed: a time the cron line promised, with no run created for it. GitHub drops queued scheduled jobs under enough load, and a dropped run leaves nothing in the Actions tab.
  • Late: a run created more than 30 minutes after its time (--late sets it). GitHub delays scheduled runs under load, most of all at the start of every hour.
  • Failed or cancelled: with how long it ran and a link to the run.
  • Green but did nothing: a run that concluded skipped, or a success shorter than a fifth of the workflow's usual successful run: every step skipped by an if:, or a job that found nothing to do.
  • Disabled: a schedule GitHub turned off after 60 days without activity in a public repo, one turned off by hand, or one in a fork, with the command that turns it back on.
  • The 60-day countdown: for a public repo, the days since the last push and the date GitHub's rule would turn its schedules off.

Each cron line is read from the workflow file on the default branch, in UTC or its timezone, and counted only from when the file last changed. GitHub's run list does not say which scheduled time a run answered, so a run belongs to the latest time due before it was created. For schedules more frequent than GitHub's delay, a late run and a missed one cannot be told apart. The count of runs that never came is right either way.

Why scheduled runs go missing

  • Why isn't my GitHub Actions schedule running? — Delayed or dropped under load, not on the default branch, disabled, or not the time you think: what GitHub documents, how to check each, and the fix.
  • Why did GitHub disable my scheduled workflow? — In a public repo GitHub turns off scheduled workflows after 60 days without activity, and forks start with them off. How to see it, re-enable, and keep it on.
  • Why didn't my cron job run? — A crontab job that did not run: the daemon, the log, the environment, % signs and time zones. And if it is a GitHub Actions schedule, its run history.

In a workflow: the GitHub Action

The Action runs the same check on the repo it runs in, with the job's own token, and writes the report to the job summary. fail-on: missed fails the job when a run never came or a schedule is disabled.

on:
  schedule:
    - cron: "23 8 * * *"
  push:
    branches: [main]
  workflow_dispatch:
permissions:
  actions: read
  contents: read
jobs:
  didrun:
    runs-on: ubuntu-latest
    steps:
      - uses: agentwares/didrun@main
        with:
          fail-on: missed

A check that runs on GitHub's scheduler shares its delays and drops. In a public repo its own schedule also falls under the 60-day rule, so run it on pushes and by hand too.

An hourly watch for scheduled runs is not built.

didrun tells you what happened when you ask. A watch would ask for you every hour, from outside GitHub's scheduler, and email you when a scheduled run is late, missed, or green with nothing done, with no change to your repo. It does not exist yet: agentcheck's free hourly watch covers MCP servers only today.

I would pay for an hourly watch of scheduled runs

The click is counted, and nothing else is sent: no form, no email, no cookie. There is no price yet and nothing is charged.