Skip to content

fix(oauth): warn before the dead localhost:8080 redirect in antigravity/gemini oauth start (#12413) - #13265

Merged
diegosouzapw merged 1 commit into
release/v3.8.51from
fix/12413-antigravity-redirect-uri
Sep 12, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.51from
fix/12413-antigravity-redirect-uri

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Closes #12413

Root cause

omniroute oauth start --provider antigravity (and any other browser-flow provider whose resolved redirect_uri is a loopback address — currently antigravity/gemini) prints the Google authorize URL and silently waits for a pasted callback. The CLI never binds a listener on the advertised port, and nothing in its own output warns the operator that the browser is about to land on a dead port before showing a confusing connection-error page. claude-code never hits this because its provider config ignores whatever redirect is requested and always uses a fixed out-of-band confirmation page.

Fix

bin/cli/commands/oauth.mjs::runBrowserFlow now checks the resolved redirect_uri with a new isLoopbackHost() helper (mirrors src/lib/oauth/providers.ts::isLoopbackHostname) right after receiving the server's authorize response and before printing the authorize URL. When the redirect is loopback, it prints a note explaining that the "can't be reached" / ERR_CONNECTION_REFUSED browser error is expected and to paste the URL anyway, and — for antigravity specifically — points at the existing omniroute login antigravity command, which already binds a real local listener and captures the code automatically.

Additive stdout text only — no change to the OAuth exchange/PKCE logic, no new network calls, no schema/DB change.

Regression test

tests/unit/probe-12413-antigravity-oauth-redirect-hint.test.ts

  • RED (before fix): AssertionError: expected the CLI to warn about the dead-redirect browser error BEFORE the user hits it, got: ... (CLI printed the authorize URL with zero warning)
  • GREEN (after fix): warning is printed for antigravity's loopback redirect; a companion case confirms the warning is NOT printed for a non-loopback redirect (claude-code's fixed platform.claude.com callback), keeping the fix scoped to genuinely dead loopback redirects.

Gates run

  • node scripts/check/check-file-size.mjs — OK
  • node scripts/check/check-complexity.mjs — OK (2798 violations, baseline 3218)
  • node scripts/check/check-cognitive-complexity.mjs — OK (1265 violations, baseline 1437)
  • npm run typecheck:core — exit 0
  • npx eslint --suppressions-location config/quality/eslint-suppressions.json bin/cli/commands/oauth.mjs tests/unit/probe-12413-antigravity-oauth-redirect-hint.test.ts — 0 errors
  • node --import tsx/esm --test tests/unit/probe-12413-antigravity-oauth-redirect-hint.test.ts — 2/2 pass
  • node --import tsx/esm --test tests/unit/9474-claude-code-oauth-mismap.test.ts tests/unit/cli-oauth-commands.test.ts (existing oauth CLI tests) — 16/16 pass, no regression
  • node scripts/check/check-changelog-integrity.mjs — OK

⚠️ base-red inherited: #12732 — unit #12058, integration codex-cache, package-artifact, tarball-smoke, agent-skills-sync

…ty/gemini oauth start (#12413)

omniroute oauth start --provider antigravity (and any other browser-flow
provider whose resolved redirect_uri is a loopback address) prints the Google
authorize URL and silently waits for a pasted callback, but nothing in the
CLI's own output warns that the browser is about to hit a dead port before
showing a confusing connection-error page. The redirect_uri the CLI advertises
(via the server's authorize response) was never bound to a real listener, and
nothing told the operator that seeing the error is expected.

Add isLoopbackHost() (mirrors src/lib/oauth/providers.ts::isLoopbackHostname)
and print a note right before opening the browser whenever the resolved
redirect is loopback, explaining the expected browser error and, for
antigravity specifically, pointing at the existing omniroute login antigravity
command which already binds a real local listener and captures the code
automatically.

Regression test: tests/unit/probe-12413-antigravity-oauth-redirect-hint.test.ts
  - RED (before fix): CLI output contained the dead localhost:8080 redirect
    with no warning
  - GREEN (after fix): warning is printed for antigravity's loopback redirect,
    and NOT printed for claude-code's fixed non-loopback redirect
@diegosouzapw
diegosouzapw merged commit bdc2fb7 into release/v3.8.51 Sep 12, 2026
15 of 21 checks passed
Githab-capibara added a commit to Githab-capibara/OmniRoute that referenced this pull request Sep 17, 2026
…ty/gemini oauth start (cheaper-inference#12413) (cheaper-inference#13265)

Merged as part of the 39-PR owner batch of 2026-09-11, validated as a unit.

Boarded into one consolidated worktree cut from `release/v3.8.51` with the other 38 — zero conflicts between them.

- ESLint over every changed file: no errors (the only finding was one suppression entry the batch emptied, pruned on cheaper-inference#13243)
- `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, within baseline); `check:changelog-integrity` OK
- complexity 2821 / baseline 3218 and cognitive-complexity 1272 / baseline 1437 — both under baseline
- 256 assertions green: 246 under node:test and 10 under vitest, which is where `tests/unit/**/*.test.tsx` actually runs
- `check-file-size`: `chatCore.ts` rebaselined 6144 → 6146 for cheaper-inference#13278 and cheaper-inference#13276, annotated and landed on cheaper-inference#13243

⚠️ base-red inherited: cheaper-inference#12732 — the provider count (356 in the docs vs the 358 the modules define) and `open-sse/utils/stream.ts` at 3115 > frozen 3098 both reproduce on the pure tip with zero contribution from this batch.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…ty/gemini oauth start (cheaper-inference#12413) (cheaper-inference#13265)

Merged as part of the 39-PR owner batch of 2026-09-11, validated as a unit.

Boarded into one consolidated worktree cut from `release/v3.8.51` with the other 38 — zero conflicts between them.

- ESLint over every changed file: no errors (the only finding was one suppression entry the batch emptied, pruned on cheaper-inference#13243)
- `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, within baseline); `check:changelog-integrity` OK
- complexity 2821 / baseline 3218 and cognitive-complexity 1272 / baseline 1437 — both under baseline
- 256 assertions green: 246 under node:test and 10 under vitest, which is where `tests/unit/**/*.test.tsx` actually runs
- `check-file-size`: `chatCore.ts` rebaselined 6144 → 6146 for cheaper-inference#13278 and cheaper-inference#13276, annotated and landed on cheaper-inference#13243

⚠️ base-red inherited: cheaper-inference#12732 — the provider count (356 in the docs vs the 358 the modules define) and `open-sse/utils/stream.ts` at 3115 > frozen 3098 both reproduce on the pure tip with zero contribution from this batch.
@diegosouzapw
diegosouzapw deleted the fix/12413-antigravity-redirect-uri branch October 18, 2026 23:48
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.

fix(auth): antigravity oauth advertises redirect_uri=http://localhost:8080/callback but never binds the port

1 participant