What this is
PR #15918 (card #15417) fixes an unconditioned yield in plugin-auth's catch-all: it handed the request on whenever better-auth answered 404, with only the status to go on, so a 404 that a routed endpoint produced — carrying real meaning, e.g. POST /auth/delete-user's "user.deleteUser is unconfigured" — was replaceable by whatever a downstream mount answered. The fix asks better-auth's live auth.api whether it owns the path and yields only when it does not.
⚠️ The @objectstack/hono adapter's /auth/* mount has the identical shape and is untouched. packages/adapters/hono/src/index.ts:343–405.
Provenance, and what is and is not measured here
⛔ This seat has not measured it. It was found by the Clause-② reviewer of PR #15918 while checking that PR's blast radius, and is recorded here rather than folded into that PR because it is a different package and outside that card's fences. The location and the "identical unconditioned yield" reading are the reviewer's; ⇒ step 1 for whoever takes this is to confirm the shape on a real boot through the adapter, exactly as #15417's own step 1 did — that step is what turned #15417 from a reported 200 {} into a measured 404 plus a different, real defect.
Why it is worth its own card rather than a note
The defect is not "a nonexistent path answers oddly" — that is composition-dependent and #15417's headline did not reproduce on a framework boot. The defect is that a 404 carrying meaning from a routed endpoint is indistinguishable, on the wire, from a path that was never claimed, so any downstream layer can overwrite it. That property travels with the yield, not with the mount, so a second mount with the same yield has the same problem regardless of which composition runs it.
⚠️ Do not assume the plugin's fix ports over unchanged. The plugin's owns() walk was validated against better-call's own router over 9282 (method, path) pairs with 0 divergences in the yield direction. Whether the adapter reaches the same auth.api instance, and whether the same walk is even available at that layer, are the first questions — not implementation details to settle later.
Known limits of the plugin-side fix, which a port would inherit
The same review measured one bounded divergence in the swallow direction: trailing-slash and doubled-slash spellings of paths better-auth does own are refused as unrouted by better-call but claimed by owns(). Non-blocking there (no in-repo route registers such spellings, and the direction favours the framework answering over a foreign mount), but a port should know about it rather than rediscover it. A one-line alignment is the plugin-side follow-up.
Related
What this is
PR #15918 (card #15417) fixes an unconditioned yield in
plugin-auth's catch-all: it handed the request on whenever better-auth answered 404, with only the status to go on, so a 404 that a routed endpoint produced — carrying real meaning, e.g.POST /auth/delete-user's "user.deleteUseris unconfigured" — was replaceable by whatever a downstream mount answered. The fix asks better-auth's liveauth.apiwhether it owns the path and yields only when it does not.@objectstack/honoadapter's/auth/*mount has the identical shape and is untouched.packages/adapters/hono/src/index.ts:343–405.Provenance, and what is and is not measured here
⛔ This seat has not measured it. It was found by the Clause-② reviewer of PR #15918 while checking that PR's blast radius, and is recorded here rather than folded into that PR because it is a different package and outside that card's fences. The location and the "identical unconditioned yield" reading are the reviewer's; ⇒ step 1 for whoever takes this is to confirm the shape on a real boot through the adapter, exactly as #15417's own step 1 did — that step is what turned #15417 from a reported
200 {}into a measured404plus a different, real defect.Why it is worth its own card rather than a note
The defect is not "a nonexistent path answers oddly" — that is composition-dependent and #15417's headline did not reproduce on a framework boot. The defect is that a 404 carrying meaning from a routed endpoint is indistinguishable, on the wire, from a path that was never claimed, so any downstream layer can overwrite it. That property travels with the yield, not with the mount, so a second mount with the same yield has the same problem regardless of which composition runs it.
owns()walk was validated against better-call's own router over 9282 (method, path) pairs with 0 divergences in the yield direction. Whether the adapter reaches the sameauth.apiinstance, and whether the same walk is even available at that layer, are the first questions — not implementation details to settle later.Known limits of the plugin-side fix, which a port would inherit
The same review measured one bounded divergence in the swallow direction: trailing-slash and doubled-slash spellings of paths better-auth does own are refused as unrouted by better-call but claimed by
owns(). Non-blocking there (no in-repo route registers such spellings, and the direction favours the framework answering over a foreign mount), but a port should know about it rather than rediscover it. A one-line alignment is the plugin-side follow-up.Related
200 {}), while a sharper defect was found underneath. Read that correction before working from the card's original framing.BETTER_AUTH_MOUNTED_SURFACEcounts the nineSERVER_ONLY/admin/oauth2/*rows as "published" though better-call never routes them — which bears on that card's premise./auth/me/permissions) and must survive any fix here, exactly as it survived fix(plugin-auth): the auth catch-all yields only a 404 that disclaims ownership #15918.