Skip to content

The "Trigger fires" card counts 2 rows per cron fire and 3 per webhook fire, because dispatchTrigger writes a 'running' row the caveat never mentions #663

Closed

Description

@serge-ivo

The triggers.fires stats card counts 2 rows per cron fire and 3 per webhook fire, and its caveat names a different reason

Found in the D1 sweep prompted by #438.

Verified — every dispatch writes a running row plus a terminal row

workers/api/src/lib/triggers.ts:296-320, dispatchTrigger:

	await recordTriggerEvent(env, trigger, sourceType, "running", { payload });      // :300
	…
		const eventId = await recordTriggerEvent(env, trigger, sourceType, "succeeded", {  // :309
	…
		await recordTriggerEvent(env, trigger, sourceType, "failed", { payload, error: message });  // :320

And the inbound webhook route writes a third before dispatching — workers/api/src/routes/triggers.ts:408-411:

	await recordTriggerEvent(c.env, trigger, "webhook", "received");
	…
	await dispatchTrigger(c.env, trigger, "webhook", payload);

Verified — the card counts rows

workers/api/src/lib/stats-sources.ts:359-366:

SELECT COUNT(*) AS v FROM agent_trigger_events
 WHERE instance_id = ?1 AND user_id = ?2 AND created_at >= ?3 AND created_at < ?4

wired as both the scalar and the daily rollup value (lib/stats-sources.ts:247 and :258).

Verified — the caveat names retries and failures, not the running row

workers/api/src/lib/stats-schema.ts:209-213:

		id: "triggers.fires",
		label: "Trigger fires",
		kinds: ["number", "line", "bar", "table"],
		describes: "Webhook and cron trigger events, grouped by status for bar/table.",
		caveat: "Counts trigger EVENTS, which includes retries and failures — it is not a count of successful work.",

A reader who accepts that caveat still expects one row per attempt. Neither the label nor the caveat says every attempt contributes a running row too.

User-visible impact

A "Trigger fires" card reads 2× reality for cron and 3× for webhook, constantly. The bar / table kinds group by status (lib/stats-sources.ts:251-253) so the parts do at least sum to the whole and a careful reader can recover the truth; the number and line kinds — the two a user glances at — have no breakdown and overstate by a fixed factor with nothing on the page to divide by.

Not claimed

Nothing inferred; all four write sites and the count query are quoted.

Refs #438.

Activity

  1. added
    P2: correctnessReal defect, no live harm today — inert fields, miscounts, missing guards
    bugSomething isn't working
    backendBackend / Worker / API work
    pipelinesPipelines, steps, triggers and the event pump — what CALLS a connector
    observabilityA displayed value the code cannot produce, or that means something other than its label
    on Aug 18, 2026
  2. serge-ivo commented on Aug 18, 2026

    @serge-ivo
    ContributorAuthor

    Audit — still LIVE. Two citations drifted; the claims all hold.

    Re-read every quoted line against main today.

    Corrected coordinates — 0cd0bfc4 (#649) and b5536ec4 (#665) both edited routes/triggers.ts, pushing the webhook write ~100 lines down:

    issue cites now at content
    routes/triggers.ts:408-411 :509 await recordTriggerEvent(c.env, trigger, "webhook", "received"); — line 408 today is cron re-anchoring, unrelated
    lib/triggers.ts:296-320 :303 / :312 / :333 the running / succeeded / failed writes; :333 is now outside the quoted range
    lib/stats-sources.ts:359-366 :362-369 the COUNT(*) scalar, unchanged
    lib/stats-schema.ts:209-213 exact the caveat, unchanged word for word

    Still true, verified: dispatchTrigger writes a running row at lib/triggers.ts:303 before doing anything, then a terminal row; the inbound webhook route writes a third at routes/triggers.ts:509; the card counts rows with no status predicate (stats-sources.ts:362-369 for number/line, :254-256 grouped for bar/table); and the caveat still names only retries and failures.

    So the arithmetic in the title is unchanged: 2 rows per cron fire, 3 per webhook fire, on the two kinds a user glances at.

    Leaving open, labels unchanged.

  3. serge-ivo commented on Aug 29, 2026

    @serge-ivo
    ContributorAuthor

    Fixed in commit a8c0faa. The triggerFires scalar/daily query and the bar/table grouped query now both filter with AND status NOT IN ('running', 'received'), so only terminal rows (succeeded + failed) are counted. One cron fire → 1; one webhook fire → 1. Three tests added to stats-sources.test.ts that inspect the generated SQL to confirm the filter lives in the query. Caveat updated to describe what is counted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2: correctnessReal defect, no live harm today — inert fields, miscounts, missing guardsbackendBackend / Worker / API workbugSomething isn't workingobservabilityA displayed value the code cannot produce, or that means something other than its labelpipelinesPipelines, steps, triggers and the event pump — what CALLS a connector

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions