Skip to content
← Guides

Your Windows scheduled task didn't run, and nothing told you.

Task Scheduler doesn't email you when a task is skipped. A script or AI agent you scheduled on a Windows machine can quietly stop running for days, and the only trace is a Last Run Result code nobody looks at. Here are the usual causes, straight from Microsoft's documentation, and how to make the next missed run reach you.

Short answer

Open the task in Task Scheduler and check its Last Run Time and Last Run Result, then the Conditions and Settings tabs: power, missed-start and instance settings are the usual culprits. Then make the task prove it ran: give it a watch in Did It Run? and end your script with a request to the watch's ping URL. If the task doesn't run, no ping arrives and you get a missed alert at the scheduled time plus your grace window, from outside the machine. Start free (3 watches, no credit card).

Check-ins are by ping URL today, with /start and /fail variants (/start marks a run as begun; it doesn't count as a finished run). Email check-ins are coming soon.

Why a scheduled task doesn't run

  • The computer was on battery. The task setting *DisallowStartIfOnBatteries* ("Start the task only if the computer is on AC power" in the Conditions tab) defaults to True, so the task won't start on battery (Microsoft Learn, DisallowStartIfOnBatteries). *StopIfGoingOnBatteries* also defaults to True, so a running task is stopped when the laptop is unplugged (Microsoft Learn, StopIfGoingOnBatteries).
  • The computer was asleep or off at the scheduled time. Task Scheduler only wakes the computer if *WakeToRun* is set (Microsoft Learn, WakeToRun). A missed start is only run later if *StartWhenAvailable* ("Run task as soon as possible after a scheduled start is missed") is on, and its default is False, and Microsoft notes it applies only to time-based tasks with an end boundary or that repeat indefinitely. When it is on, the late run is queued and started after a delay, 10 minutes by default (Microsoft Learn, StartWhenAvailable).
  • The previous run was still going. The *MultipleInstances* setting decides what happens when a run is due while another is running. With TASK_INSTANCES_IGNORE_NEW, the new run simply isn't started (Microsoft Learn, MultipleInstances). A hung script can block every run after it.
  • It was stopped for running too long. By default a task is stopped 72 hours after it starts (Microsoft Learn, TaskSettings); you can change this with *ExecutionTimeLimit* (Microsoft Learn, ExecutionTimeLimit).
  • It needs the network and there wasn't any. *RunOnlyIfNetworkAvailable* holds the task back when no network is available (Microsoft Learn, RunOnlyIfNetworkAvailable).
  • The task is disabled or has no more runs. Task Scheduler reports these as status codes, not alerts: 0x41301 means the task is disabled, 0x41302 that it has not yet run, 0x41303 that there are no more runs scheduled (Microsoft Learn, Task Scheduler error and success constants).

In every one of these cases nothing is sent to you. You'd have to open Task Scheduler to notice.

Step 1: read what Task Scheduler recorded

  1. Open Task Scheduler, find the task, and read Last Run Time, Next Run Time and Last Run Result. Look up the result code in Microsoft's list of error and success constants.
  2. On the Conditions tab, check the power settings and whether Wake the computer to run this task is ticked.
  3. On the Settings tab, check Run task as soon as possible after a scheduled start is missed, Stop the task if it runs longer than, and If the task is already running.

Step 2: add a heartbeat so a missed run reaches you

  1. Create a watch in Did It Run? with the same schedule as the task, in the same timezone, with a grace window that covers the task's normal run time (plus 10 minutes if you rely on *StartWhenAvailable* catch-up).
  2. Add a check-in as the last step of your PowerShell script, and a /fail check-in when it errors:
powershell
$url = "<your watch's ping URL>"
$ErrorActionPreference = "Stop"   # make cmdlet errors jump to catch
try {
  # ... your job ...
  # A program (.exe) that fails doesn't throw; check its exit code:
  # some-tool.exe --args
  # if ($LASTEXITCODE -ne 0) { throw "some-tool exited $LASTEXITCODE" }
  Invoke-RestMethod -Method Post -Uri $url -Body "run complete"
} catch {
  Invoke-RestMethod -Method Post -Uri "$url/fail" -Body "$_"
  exit 1
}

Now each case is covered:

  • The task didn't run (battery, asleep, previous run still going, disabled): no ping arrives, so the run is missed at the deadline.
  • The script ran and failed: it calls /fail and you get a failed alert. The alert shows the first 200 characters of the error text you send.
  • The script ran, but on nothing: send a count in the body and set an output sanity check on the watch; see Scheduled job ran but output was empty.

If the job is the kind that could hang, also see Cron job or AI agent hung with no error.

Honest limits

  • Did It Run? doesn't connect to your Windows machine or read Task Scheduler. It only sees the check-ins your script sends.
  • A missed alert tells you the run didn't arrive, not why. Step 1 is how you find out which cause it was.
  • If the machine has no internet when the script finishes, the check-in can't arrive and the run shows up as missed, which is the safe way round.

What you'll see

  • Missed: no check-in by the expected time plus grace.
  • Late: an optional early warning while the run is still inside its grace window.
  • Failed: the script called /fail.
  • Empty: the check-in arrived but failed the watch's sanity check.
  • Recovered: the first good run after a problem.

Free covers 3 watches with email alerts; Solo ($15/month) adds Slack, Discord and Telegram alerts and a daily roll-call digest across all your automations.

FAQ

Why didn't my scheduled task run on my laptop?

Most often power. By default a task won't start while the computer is on battery, and a running task is stopped when the computer goes onto battery. Check the Conditions tab. If the laptop was asleep, the task only wakes it when Wake the computer to run this task is set.

Does Task Scheduler run a task it missed while the computer was off?

Only if Run task as soon as possible after a scheduled start is missed (StartWhenAvailable) is on. Its default is off. When on, the late run is queued and started after a delay, 10 minutes by default.

What does Last Run Result 0x41302 mean?

Microsoft lists 0x41302 as SCHED_S_TASK_HAS_NOT_RUN: the task has not yet run. 0x41301 (SCHED_S_TASK_DISABLED) means the task is disabled, and 0x41303 (SCHED_S_TASK_NO_MORE_RUNS) means there are no more runs scheduled.

Can Task Scheduler alert me when a task doesn't run?

Task Scheduler records the result but doesn't send you an alert for a skipped run. An outside heartbeat watch that expects a check-in on schedule catches it, because a run that never happens sends nothing.

Can I check in by email instead of a URL?

Not yet. Email check-ins are coming soon. Today every check-in is an HTTP request to the watch's ping URL, with /start and /fail variants.

Know the next time it doesn't run

Add one ping URL to the end of your job. If the ping doesn't arrive on time, Did It Run? emails you.

Free for 3 watches. No credit card.

Start free: 3 watches