Skip to content

Stop automatic retries of failed queued messages - #2830

Merged
ymichael merged 3 commits into
mainfrom
bb/fixer-stop-automatic-retries-after-queue-failure-thr_i5e9x8jndj
Sep 1, 2026
Merged

Stop automatic retries of failed queued messages#2830
ymichael merged 3 commits into
mainfrom
bb/fixer-stop-automatic-retries-after-queue-failure-thr_i5e9x8jndj

Conversation

@ymichael

@ymichael ymichael commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Human comments

What was wrong

The durable queue introduced in #2779 records a background dispatch failure on the queued row. Automatic selectors did not exclude that failed state, so later sweeps could keep running plugin hooks and dispatch preparation without an explicit retry.

There was also a grouped-message race: even after filtering failed rows from the selectors, a clean member could enter the atomic claim and pull a failed member from the same group back into an automatic attempt.

What changed

The shared database selectors exclude terminally failed rows from automatic drains. The atomic grouped-claim boundary now also requires every group member to have no failure whenever an automatic eligibility callback is present. This closes both the clean-member bypass and a failure recorded after selection.

Explicit Send now claims without that automatic callback, so users can still retry failed messages deliberately. Failed rows remain visible through the API and UI.

Normal temporary conditions such as a busy thread, future schedule, provisioning, pending interaction, plugin wait, disconnected host, and host-command timeout do not enter the failed state and still recover automatically.

There are no schema, migration, host-daemon protocol, CLI, configuration, SDK, or documentation changes.

How you verified

  • Added a production database/server sweep regression that failed before the fix with three hook attempts instead of one, then passed after the fix while proving the failed row remained explicitly claimable by ID.
  • Added grouped scheduled and requested-plugin service regressions. Before the transactional guard, each incorrectly invoked the dispatch hook once; afterward, both leave the two-row group untouched with zero attempts.
  • pnpm exec turbo run test typecheck build --filter=@bb/db --filter=@bb/server --force on the rebased tree — DB 442 tests passed, server 2124 tests passed, and typechecks/builds passed.

Fixes #2779

AGENT GENERATED

@ymichael

ymichael commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator Author

@slopcop

@bb-slop-cop

bb-slop-cop Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

🚨 SLOP COP 🚨 · review

I am the Slop Cop. I am reviewing this pull request now.

I will check security, code quality, performance, architecture, duplication, and the user flow.

Comment thread packages/db/src/data/queued-thread-messages.ts

@bb-slop-cop bb-slop-cop Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 SLOP COP 🚨 · review

Plain English summary: This change stops bb from automatically trying a failed queued message again. The user can still send it manually.

I found one high-severity correctness defect.

A clean member of a grouped message can claim a failed member during a scheduled or plugin drain. This action retries the failed message automatically.

The new selector filter checks each reference row. The later atomic claim rebuilds the complete group and checks only its deadline or wait holder.

The fix must check failureReason for every group member inside the claim transaction. The explicit Send now path must stay unchanged.

Please add grouped regression tests for the scheduled drain and the requested-plugin drain.

The architecture search found no other raw automatic selectors outside the database data module. The shared predicate removes useful duplication.

The performance review found no regression. The existing partial indexes remain active.

As an optional follow-up, the partial due and wait-holder indexes can exclude failed rows. This change can reduce stale index entries.

Verification passed:

  • 29 focused server tests.
  • 66 focused database and query-plan tests.
  • Type checks for @bb/db and @bb/server.
  • A browser smoke test of the local app, with no console errors.

I used a comment review. I did not approve this pull request or request changes.

@ymichael
ymichael force-pushed the bb/fixer-stop-automatic-retries-after-queue-failure-thr_i5e9x8jndj branch from 0c064cf to 61d7d4e Compare September 1, 2026 22:12
@ymichael
ymichael merged commit e9ad57b into main Sep 1, 2026
15 checks passed
@ymichael
ymichael deleted the bb/fixer-stop-automatic-retries-after-queue-failure-thr_i5e9x8jndj branch September 1, 2026 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant