Skip to content

[quality] worker.ts queue(): per-message ack/retry isolation is never driven with a batch of two, and wrangler.toml's max_batch_size = 1 is unpinned #696

Open

Description

@hivecommons-hive

Finding

queue() in src/server/worker.ts walks batch.messages and acks or retries each message inside its own try/catch, so a message whose run throws is retried on its own: the messages behind it in the batch still run, and the ones already acked are not carried by the retry. Nothing drives that loop with more than one message:

  • wrangler.toml sets max_batch_size = 1, and __tests__/worker/worker.test.ts builds its miniflare with maxBatchSize: 1. Every consumer test therefore sees a single-message batch; the three "retried, not acknowledged" tests prove the retry of a lone message, not the isolation of its batch-mates.
  • max_batch_size = 1 itself is unpinned. __tests__/worker/wranglerConfig.test.ts pins the producer/consumer queue names, the dead-letter queue, the Durable Object migrations and the cron trigger, but not the batch size — and that 1 is what makes "the consumer runs the scheduled jobs for that installation only, within one invocation's budget" (feat(app): run on Cloudflare Workers; Platform.defer() for the grace period #615) true. A dependabot-style or well-meaning raise to the default (10) would pass every test.

Evidence at main@9aa12b8:

  • Unit: src/server/worker.ts is excluded from vitest --coverage (vitest.config.mjs) and from both Stryker sets; the miniflare suite under __tests__/worker is its only evidence, and that suite is single-message throughout (grep maxBatchSize __tests__/worker → one site, 1).
  • End-to-end: npm run test:coverage:e2e measures the action bundle, which does not contain the Worker.
  • Mutant check: with the per-message try/catch removed from queue() and dist-worker rebuilt, a two-message batch [schedule 7 (fails), schedule 9] never lists installation 9's repositories at all (the first throw aborts the invocation and the retry hits the same wall) — and every existing worker test still passes.

Recommendation

  • In __tests__/worker/wranglerConfig.test.ts, pin queueConsumers['prow-jobs'].maxBatchSize === 1 through wrangler's own unstable_getMiniflareWorkerOptions translation, next to the existing queue/DLQ pins.
  • Add __tests__/worker/queueBatch.test.ts: the same dist-worker/worker.js under maxBatchSize: 2, maxRetries: 1, sendBatch of two schedule messages where the fake GitHub fails installation 7's repository listing and serves installation 9's; assert installation 7 is listed twice (retried once), installation 9 exactly once (ran behind the failure, acked, not carried by the retry), and 7's listing is the first seen.

Both verified to fail without the behaviour they pin (batch size raised to 2 / the per-message try/catch removed) and pass with it.

Priority

  • Impact: medium — the loop is the Worker's only error boundary for queue work; the batch-size pin is what keeps one installation's scheduled run from sharing an invocation with others
  • Effort: low

Filed by quality agent (hold-gated mode)


🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: 9aa12b8

— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/qualityCreated by Hive for agent-filed issue provenancekind/cleanupCategorizes issue or PR as related to cleaning up code, process, or technical debt.stage/040-covered-by-prAn open PR covers this issuetestingCreated by Hive for agent-filed issue provenance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions