Skip to content

Why didn't my watch fire?

Something happened in the world, and Watcher said nothing. Work through this in order — it takes about two minutes.

  1. Open the watch’s run history: in the panel, in the app, with pnpm watches history <id>, or GET /watches/:id/runs.

  2. Find the run that covers the time the event happened.

  3. Read its outcome word. That single word tells you which stage stopped the run.

OutcomeWhat happenedWhat to do
disabledThe watch is switched off, so nothing was collected or evaluated.Enable the watch if you expected it to run.
no-candidatesSources ran without error but returned no items at all.Check the source still returns content — an empty feed, an empty search, or a page that extracted nothing.
collection-failedEvery source that was tried threw an error.Look at the recorded source errors. A health alert is also sent for this outcome.
nothing-newItems were collected, but every one had already been seen on a previous run.Nothing. This is the normal outcome on a quiet day and costs no model calls.
not-triggeredFresh content was evaluated and the model decided the condition was not met.If you disagree, the condition or the sources are usually the problem, not the threshold.
below-thresholdThe model triggered, but the result did not clear the bar — either low confidence, or a quality check failed and there was no weak tier to fall back to.Check the run record: an ungrounded quote or an ungraded source demotes an otherwise confident verdict.
already-notifiedThe triggered event has the same identity as one already alerted on.Nothing. Deduplication working as intended.
semantic-duplicateThe event is a reworded version of one recently alerted on (embedding similarity at or above 0.92).Nothing, unless you believe it was genuinely a different event.
notifiedAn alert fired and was delivered on at least one channel.Read the alert. Optionally label it to feed the accuracy dashboard.
notify-failedThe alert was real and passed every check, but every configured channel failed to deliver it.Fix the channel. Delivery is retried automatically for up to five attempts.

Watcher fetched your sources and every item was one it had already read.

  • The page changed but the extracted text did not. Common on portals where the news is in a JavaScript-rendered widget while the extracted text is a static shell. Confirm with Sources return nothing.
  • The news is not on the page you are watching. Add a search source so Watcher can find it wherever it landed.

The model read genuinely new content and decided your condition was not met.

  • Read the run’s reasoning. It is stored on the run record and shown in the panel — it usually says exactly why.
  • Make the condition concrete. “result” is a keyword; “the official result or scorecard for X has been declared” is a question a model can answer.
  • Check the content actually contains the news. If the collected text is a navigation shell, no condition will match.
  • Remember: the model is instructed not to trigger on speculation or “coming soon”, and not to re-fire on a restatement of something you were already told.

Something triggered but did not clear the bar. This is the outcome with the most possible causes — and the run record narrows it down:

Look for Cause Fix
Confidence just under your threshold The bar is set high Lower threshold, or add weakThreshold so borderline hits surface as unconfirmed
No evidence quote on the record The verdict was ungrounded and cannot fire strong Usually a thin or badly extracted page
corroboratingTier is unknown The source is not graded, and ungraded sources cap at weak Add a trust rule for that domain
Two models consulted, alert still weak The second opinion disagreed Genuinely ambiguous evidence — consider a weak tier
minSources: 2 set, one source had the news Corroboration not met Add a second source, or drop minSources

Watcher believes it already told you. Check whether you actually received that earlier alert — if you did not, this is a delivery problem, not a detection one. Go to Alerts are not arriving.

Nothing was collected at all. See Sources return nothing.

Watcher decided correctly and could not deliver. The alert is queued and will be replayed automatically. See Alerts are not arriving.

Check How
Is it enabled? pnpm watches:list, or the toggle in the panel
Is it due? Cron is UTC. A watch runs at the slower of its own cron and the instance’s schedule
Did the instance run? Check your scheduled job’s logs, or the service logs
Was it imported? Editing watches/*.yml does nothing until pnpm watches:import

Test it immediately, bypassing all scheduling:

Terminal window
pnpm run-due:force