{"slug": "the-cloudflare-worker-that-ran-perfectly-and-still-failed-twice", "title": "The Cloudflare Worker That Ran Perfectly and Still Failed Twice", "summary": "A developer building workers-monitor, a Cloudflare Worker that monitors a fleet of Workers, discovered two bugs where code compiled and ran without errors but failed to perform its intended function. The first bug involved a maintenance-window feature that could silently abort the entire hourly run on a KV read failure, violating the rule that malformed data must fail open. The second bug was that Sentry monitoring for the Worker itself was not actually reporting check-ins despite successful execution, requiring a fix to ensure proper cron monitoring.", "body_md": "*This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry.*\n\n`workers-monitor`\n\nis a Cloudflare Worker that watches a small fleet of my\n\nown Workers. Hourly cron, pulls fleet metrics from Cloudflare's GraphQL\n\nAnalytics API, runs a deterministic threshold gate, and only calls Claude\n\nHaiku to judge signal-vs-noise if the gate trips. If Haiku confirms\n\nsomething's actually wrong, it sends a Telegram alert. A quiet hour makes\n\nzero LLM calls.\n\n[github.com/dannwaneri/workers-monitor](https://github.com/dannwaneri/workers-monitor)\n\nReal alert history from the deployed Worker — the daily heartbeat, and\n\nscrolled back, the genuine incidents this system has actually caught.\n\nThis submission covers two bugs, found days apart, that turn out to be\n\nthe same failure mode wearing different clothes: code that compiles,\n\ndeploys cleanly, and runs without throwing — and still doesn't do the one\n\nthing it was written for. \"No error\" is not the same claim as \"working\n\ncorrectly,\" and both bugs below only exist because that distinction got\n\nmissed once.\n\n`workers-monitor`\n\nhas a maintenance-window feature — `POST`\n\na start/end\n\ntime and it suppresses Telegram alerts during a planned deploy, without\n\nstopping the gate or the logging. The function that reads that window had\n\none non-negotiable rule, written as a comment directly above it:\n\nMalformed data fails OPEN (returns null → no suppression) — a broken\n\nwindow read must never accidentally silence a real incident.\n\nThe code didn't actually satisfy that comment:\n\n```\nasync function readMaintenanceWindow(env: Env): Promise<MaintenanceWindow | null> {\n  const raw = await env.STATE.get(MAINTENANCE_KEY);\n  if (!raw) return null;\n  try {\n    const w = JSON.parse(raw) as MaintenanceWindow;\n    if (Number.isNaN(Date.parse(w.start)) || Number.isNaN(Date.parse(w.end))) {\n      throw new Error(\"unparseable start/end timestamps\");\n    }\n    return w;\n  } catch (err) {\n    console.error(/* ... */);\n    return null;\n  }\n}\n```\n\nOnly `JSON.parse`\n\nand the timestamp validation sit inside the `try`\n\nblock\n\n— `await env.STATE.get(...)`\n\non the line above does not. A genuine KV\n\nread failure (a real outage, not bad data) throws an exception nothing in\n\nthis function catches. It propagates out of `readMaintenanceWindow`\n\n, out\n\nof the `run()`\n\nfunction that calls it, and aborts the entire hourly run —\n\nnot just alert suppression, but the deterministic gate, the Haiku\n\njudgement call, and the structured logging for that hour, all of it,\n\nsilently skipped. Every KV blip during that window meant a full hour of\n\nzero fleet visibility, not just a missed alert.\n\nI found this via a structured review of the diff against the original\n\nspec's acceptance criteria, not a live incident. One criterion was almost\n\nword-for-word the comment above the function — the review caught that the\n\ncode only satisfied half of that sentence.\n\nFixing bug 1 raised an obvious follow-up question: what happens when\n\n`workers-monitor`\n\nitself breaks, not the fleet it watches? Nothing —\n\nconsole.error into `wrangler tail`\n\n, unread unless I happened to be\n\nwatching. So I wired in Sentry: `Sentry.withSentry()`\n\naround the handler\n\nfor automatic error capture, an explicit `Sentry.captureException()`\n\non\n\nthe deliberately-swallowed exception in the scheduled handler's own\n\ncatch, and `Sentry.withMonitor()`\n\naround the hourly `run()`\n\ncall so a\n\ndead cron trigger gets caught immediately instead of waiting up to 24\n\nhours for the next Telegram heartbeat to go silent.\n\nI deployed it, watched a cron tick complete without error, and considered\n\ncron monitoring done.\n\nIt wasn't done. While recording a demo video of the Sentry integration —\n\nfor a separate piece of this challenge — I opened the Monitors dashboard\n\nto screenshot the cron check-in, and there wasn't one. Only Sentry's own\n\nauto-created generic \"Error Monitor,\" nothing for `workers-monitor-hourly-poll`\n\nat all, despite the code executing successfully every hour for days.\n\n``` js\nSentry.withMonitor(\"workers-monitor-hourly-poll\", () => run(event, env))\n```\n\nThis isn't wrong syntax. It compiles, deploys, executes the wrapped\n\nfunction fine. But the check-in has nowhere to attach without a schedule\n\n— Sentry needs to know what \"on time\" means for this monitor before it\n\nwill create a Cron Monitor entity to check in against. Without that\n\nconfig, the call silently has no monitor to report to. No error, no\n\nwarning, just nothing showing up. Exactly the same shape as bug 1: code\n\nthat runs clean and still isn't doing its job.\n\n[github.com/dannwaneri/workers-monitor/pull/1](https://github.com/dannwaneri/workers-monitor/pull/1) — the fail-open fix, isolated, 12 insertions / 1 deletion.\n\n[github.com/dannwaneri/workers-monitor/pull/3](https://github.com/dannwaneri/workers-monitor/pull/3) — the cron monitor fix, isolated, 14 insertions / 1 deletion.\n\n```\n// Bug 1 fix — env.STATE.get() gets its own try/catch, separate from the\n// existing one around JSON.parse:\nasync function readMaintenanceWindow(env: Env): Promise<MaintenanceWindow | null> {\n  let raw: string | null;\n  try {\n    raw = await env.STATE.get(MAINTENANCE_KEY);\n  } catch (err) {\n    console.error(JSON.stringify({\n      event: \"maintenance_window_read_error\",\n      error: err instanceof Error ? err.message : String(err),\n    }));\n    return null;\n  }\n  if (!raw) return null;\n  try {\n    const w = JSON.parse(raw) as MaintenanceWindow;\n    if (Number.isNaN(Date.parse(w.start)) || Number.isNaN(Date.parse(w.end))) {\n      throw new Error(\"unparseable start/end timestamps\");\n    }\n    return w;\n  } catch (err) {\n    console.error(/* ... */);\n    return null;\n  }\n}\n// Bug 2 fix — the missing monitorConfig, matching the real deployed schedule:\nSentry.withMonitor(\n  \"workers-monitor-hourly-poll\",\n  () => run(event, env),\n  {\n    schedule: { type: \"crontab\", value: \"0 * * * *\" }, // matches wrangler.jsonc's trigger\n    checkinMargin: 5, // minutes late before considered missed\n    maxRuntime: 5,    // minutes before considered timed out\n    timezone: \"UTC\",  // Cloudflare cron triggers always run in UTC\n  },\n)\n```\n\nNeither fix is large. What connects them is how each was actually\n\nverified, not assumed:\n\nFor bug 1, I ran a two-part review before trusting the diff: does it\n\nsatisfy every Given/When/Then acceptance criterion from the original\n\nspec, and separately, does it resolve every assumption flagged during\n\ndesign, including ones nobody had explicitly revisited. That second check\n\nis what surfaced it — the acceptance criterion for KV-failure behavior\n\nwas already written down before the code existed, and the implementation\n\nsimply didn't fully match its own spec.\n\nFor bug 2, the same discipline applied to my own claim: I'd told myself\n\n\"deployed, ran without error, cron monitoring is working.\" I checked the\n\nMonitors dashboard before the fix (empty — confirmed the bug was real,\n\nnot a hunch), deployed the fix, waited for a genuine production cron\n\ntick — not a local test, not a manual trigger — and only considered it\n\ndone once `workers-monitor-hourly-poll`\n\nactually appeared as a registered\n\nCron monitor with an \"Every hour\" schedule.\n\nThe broader lesson, true of both bugs: \"the code deployed and nothing\n\ncrashed\" is a dramatically weaker claim than \"the thing I built does what\n\nI said it does.\" Those two can look identical from a terminal and be\n\ncompletely different in reality.\n\nBoth Error Monitoring and Cron Monitoring are used here, and bug 2 is\n\nspecifically about making the Cron Monitoring half actually work as\n\nintended, not just installed:\n\n`Sentry.withSentry()`\n\nwraps the handler,\ninstrumenting `fetch`\n\nand `scheduled`\n\n.`try/catch`\n\nso one bad run\ndoesn't crash the Worker. That's exactly the case `withSentry`\n\n's\nautomatic uncaught-exception capture can't see, since the exception is\ncaught before it ever becomes \"uncaught\" — so the catch block also\ncalls `Sentry.captureException(err)`\n\ndirectly.`workers-monitor-hourly-poll`\n\nshows up as a real Cron monitor with an\n\"Every hour\" schedule. If the trigger stops firing entirely, Sentry\nnow catches that immediately, instead of the previous 24-hour blind\nspot (the daily Telegram heartbeat was the only prior proof-of-life).**Verified, not assumed**, on both fronts: for error capture, I deployed\n\na temporary route that threw an intentional error, confirmed it was\n\ncaptured in the Sentry dashboard, then removed the route before opening\n\nthe PR. For cron monitoring, the Monitors dashboard was checked empty\n\nbefore the fix and populated after a real hourly tick — not a claim, a\n\nbefore/after I watched happen.\n\nThe resolved issues, the real stack trace, and the moment the cron\n\nmonitor actually registered — the same evidence, on screen.", "url": "https://wpnews.pro/news/the-cloudflare-worker-that-ran-perfectly-and-still-failed-twice", "canonical_source": "https://dev.to/dannwaneri/the-cloudflare-worker-that-ran-perfectly-and-still-failed-twice-17l2", "published_at": "2026-07-27 08:40:07+00:00", "updated_at": "2026-07-27 09:07:06.121520+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools"], "entities": ["Cloudflare", "Sentry", "Claude Haiku", "workers-monitor", "GraphQL Analytics API", "Telegram"], "alternates": {"html": "https://wpnews.pro/news/the-cloudflare-worker-that-ran-perfectly-and-still-failed-twice", "markdown": "https://wpnews.pro/news/the-cloudflare-worker-that-ran-perfectly-and-still-failed-twice.md", "text": "https://wpnews.pro/news/the-cloudflare-worker-that-ran-perfectly-and-still-failed-twice.txt", "jsonld": "https://wpnews.pro/news/the-cloudflare-worker-that-ran-perfectly-and-still-failed-twice.jsonld"}}