a24f420 (#107) gave the register gate a captured body and one retry, to survive kubectl run -i losing a short-lived pod's output. The retry cannot actually save the case it was built for, because registration is not idempotent.
Observed on main at 1fc15f3, 2026-08-07 20:06 UTC (run):
── the account path: register, verify, get a key ──
(registration pod produced no output — attach flake, retrying once)
curl: (22) The requested URL returned error: 422
pod fountain/e2e-register-2 terminated (Error)
✗ e2e: registration did not return a user_id
Attempt 1 registered the account and lost its output. Attempt 2 re-posted the same address, hit the unique-email constraint, and returned 422 — so the gate reported that registration failed, which is precisely the false red the retry exists to prevent.
The existing comment anticipates the mechanism but reads it as acceptable:
Registering the same address twice cannot double-register: the second attempt fails on the unique email, which still fails this gate — the retry only forgives losing the answer, never the act.
That holds when attempt 1 genuinely did not register. But the likelier attach-flake shape is the one seen here — the pod ran, the act happened, only the answer was lost — and there the retry converts a lost answer into a hard failure. The retry helps in the rarer half of the cases and is inert in the common one.
This is the same root flake as #111's red first-admin gate, fixed for the eval-pod recipes in #112. Those two were safe to retry only because promote_admin/1 and Accounts.verify_email/2 are idempotent. Registration is the one that isn't, which is why it needs a different answer rather than the same loop.
A fix that does not weaken the gate
On attempt 2, a 422 / has already been taken for the address attempt 1 used is not a failed registration — it is attempt 1's receipt, arriving by the only route left once its own output was lost. Accepting it costs nothing in assertion strength:
user_id is only ever a presence check (grep -q user_id). It is never captured and nothing downstream uses it.
- The next line runs
just verify-email "$email", which hard-fails with no account for … if the account does not exist. A non-existent account still cannot get through the gate.
Sketch:
reg=""; registered=""
for attempt in 1 2; do
reg="$(kubectl run "e2e-register-$attempt" … || true)"
if printf '%s' "$reg" | grep -q user_id; then registered=yes; break; fi
if [ "$attempt" = 2 ] && printf '%s' "$reg" | grep -qE '422|already been taken'; then
echo " (attempt 1 registered after all — the 422 on the retry is its receipt)"
registered=yes; break
fi
echo " (registration pod produced no output — attach flake, retrying once)"
done
[ -n "$registered" ] || { printf '%s\n' "$reg" | tail -5; fail "registration did not return a user_id"; }
Frequency
Twice in one day, both on CI runners: once on #111 (the first-admin gate, a different recipe, same root cause) and once here on main. Both passed on a rerun of identical input, so the current cost is a rerun per occurrence plus the time spent deciding whether the red was real — on #111 it was misread as a possible fountain-pin regression before the evidence ruled that out.
Raised rather than fixed as part of #112, which was scoped to the eval-pod recipes.
a24f420(#107) gave the register gate a captured body and one retry, to survivekubectl run -ilosing a short-lived pod's output. The retry cannot actually save the case it was built for, because registration is not idempotent.Observed on
mainat1fc15f3, 2026-08-07 20:06 UTC (run):Attempt 1 registered the account and lost its output. Attempt 2 re-posted the same address, hit the unique-email constraint, and returned 422 — so the gate reported that registration failed, which is precisely the false red the retry exists to prevent.
The existing comment anticipates the mechanism but reads it as acceptable:
That holds when attempt 1 genuinely did not register. But the likelier attach-flake shape is the one seen here — the pod ran, the act happened, only the answer was lost — and there the retry converts a lost answer into a hard failure. The retry helps in the rarer half of the cases and is inert in the common one.
This is the same root flake as #111's red first-admin gate, fixed for the eval-pod recipes in #112. Those two were safe to retry only because
promote_admin/1andAccounts.verify_email/2are idempotent. Registration is the one that isn't, which is why it needs a different answer rather than the same loop.A fix that does not weaken the gate
On attempt 2, a
422 / has already been takenfor the address attempt 1 used is not a failed registration — it is attempt 1's receipt, arriving by the only route left once its own output was lost. Accepting it costs nothing in assertion strength:user_idis only ever a presence check (grep -q user_id). It is never captured and nothing downstream uses it.just verify-email "$email", which hard-fails withno account for …if the account does not exist. A non-existent account still cannot get through the gate.Sketch:
Frequency
Twice in one day, both on CI runners: once on #111 (the first-admin gate, a different recipe, same root cause) and once here on
main. Both passed on a rerun of identical input, so the current cost is a rerun per occurrence plus the time spent deciding whether the red was real — on #111 it was misread as a possible fountain-pin regression before the evidence ruled that out.Raised rather than fixed as part of #112, which was scoped to the eval-pod recipes.