The plan sorts the offers it draws by weight alone. Two tariffs an operator never weighted tie, and the database is then free to answer in either order. The plan draws them in that order, and a seat clicked without choosing an offer takes the first, so the same click books a different price on different page loads. A rule attached to one of the two reaches the booking only sometimes.

Weight and then id, which this same file already does two hundred lines further down for the venue’s own rows. First created wins, which is stable and is what an operator who never reordered anything would expect.

What this actually was, and what it was not

It surfaced as a browser test failing about one run in eighty, and five explanations were wrong before the right one: that it was specific to the next major lane (it reproduces on both), that the wait budgets were too tight (twenty seconds against an assertion that resolves in well under one), that a held element handle meant a click reached a node that had left the document (both clicks reached the server and were answered), that two requests from one booker overlapped (the click queue is a no-op while a request is out, so the second click is remembered rather than sent), and that a per-transaction ceiling was being bypassed (it was never asked).

What settled it was the trace: the request resolved the hosts governing the line and found no attachment at all, on the right tariff, with the attachment sitting in storage. The two readings were of different tariffs. The scenario capped one of its two prices and the click booked the other, so the engine looked for a ceiling on what was being booked, correctly found none, and correctly held both places. Every response body had said so from the first capture, naming tariff 4 while the ceiling was on tariff 3.

So there is no overbooking hole and nothing to serialize. This issue was filed as a test-stability problem and then retitled as a critical engine one; both were wrong, and the second was wrong on evidence that turned out to be another test class’s entries in a shared trace file.

The test was wrong too, separately

It claimed to test that a seat refused by a ceiling is not painted as taken, and never established the condition that claim needs: that the click books the tariff it capped. On the runs where it did not, the scenario exercised a different situation and reported the resulting booking as a refusal that never came. It now asserts both halves of its premise before clicking, that the ceiling is really attached and that it is attached to the offer the click will use, and with the order reversed it fails on that at once rather than twenty seconds later on a live region.

Verification

A regression test builds two tariffs nobody weighted and asserts they come back in the order they were made; it fails when the tie-break is reversed. The browser scenario was then sampled fifteen times a pipeline under the suite’s ordinary concurrency, fanned out ten pipelines at a time: three hundred samples with the fix, no failures, against a rate that had been about one in sixty. The sampler and every trace it needed are reverted, and the CI file is byte-identical to 1.x again.

Not in this change

Twenty-two find(...)->click() sites remain in the two picker tests, each holding an element handle across two round trips with a redraw behind it. That is a real defect by the rule the test trait states about itself, and it is not what this was: worth its own change. The queue’s watchdog also clears its in-flight flag after fifteen seconds without the answer having arrived, which is unsafe on its own terms and did not cause this.

AI-Generated: Yes (Claude Code found this, misdiagnosed it five times, built the sampler that settled it, and wrote this summary. Two of the sampling rounds were wasted by its own instrumentation: a trace through state broke a query-count assertion in every job, and a shared trace file fed it another test class’s entries, which is what the critical retitling rested on.)

Issue fork yoyaku-3618773

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Title: The picker browser tests fail intermittently on the next major lane, so its green is not trustworthy » A per-transaction ceiling can be exceeded when one booker’s requests overlap
Priority: Major » Critical
Issue summary: View changes
mably’s picture

Status: Active » Needs review
mably’s picture

Title: A per-transaction ceiling can be exceeded when one booker’s requests overlap » Order the plan’s offers by weight and then by id, so a bare seat click always books the same one
Priority: Critical » Normal
Issue summary: View changes

  • mably committed efea6483 on 1.x
    fix: #3618773 Order the plan’s offers by weight and then by id, so a...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.