Signed out, open a dashboard link carrying prop=*@org, click Sign in with Google: before, Better Auth refused the callbackURL; after, the browser lands on Google's sign-in.
18 Sept 2026 · branch login/k1-callback-url-encode · captured against propflow-stage · at 443bc0623f
Data note. Every name and balance below comes from propflow-stage, which is anonymized by construction (ADR-0097/0110 — phones in the impossible +1000 NPA, emails @example.test). The identical capture against prod would carry real tenants' names and balances and is not safe to attach anywhere, which is why the generator refuses to run against one.
This is origin/main without the fix, served by a dev server bound to propflow-stage. The page is exactly what middleware produces for the reported link: /login?from=/dashboard?org=…&prop=*%40…. Clicking Sign in with Google POSTs the vetted from value to Better Auth as callbackURL, and Better Auth answers 403 {"code":"INVALID_CALLBACK_URL"} — its relative-callbackURL regex admits no * in a query. The page renders the message and nothing else happens.
Asserted in the captured DOM — Sign in with Google · Invalid callbackURL. The error copy is asserted in rendered text, in the state the screenshot shows — after the click.
Same page, same click, on this branch. toAuthCallbackURL rewrites the vetted value to /dashboard?org=…&prop=%2A%40… — the one character Better Auth refuses is percent-encoded and the existing %40 passes through untouched. Better Auth answers 200 {"url":"https://accounts.google.com/…"} and the browser navigates there: Google's own Sign in to continue to Propflow screen, captured cross-origin. No "Invalid callbackURL" anywhere on the path. On the way back, useSearchParams().get('prop') decodes %2A%40 to *@, so the landing selection is the one the link carried.
Asserted in the captured DOM — to continue to · Propflow · Email or phone. Asserted on Google's own page text after the cross-origin navigation (its heading splits "Sign in" / "to continue to" / "Propflow" across elements) — the proof is that the browser got there at all.
The BEFORE is the bug as reported (Gera, 2026-09-18, walking onboarding signed out). The AFTER is the same browser, the same click, reaching Google. The unit tests in auth-return-to.test.ts pin the encoder against a copy of Better Auth's regex; login-google-signin-hang.test.tsx pins that both Better Auth call sites on /login use it. This page pins the thing neither can: that the real Better Auth in the real server accepts the result.