Repository navigation
fix(antigravity): send complete loadCodeAssist metadata (ideType/platform/pluginType as numeric enums) - #11969
Merged
diegosouzapw merged 1 commit intoAug 30, 2026
Conversation
…form/pluginType as numeric enums)
loadCodeAssist and onboardUser both returned 403 for every account on a
live deployment, even accounts with completed Gemini Code Assist
onboarding. Traced via live log comparison (same Google account, same
host) against the sibling 9router project, which succeeds against the
identical account: OmniRoute's getAntigravityLoadCodeAssistMetadata()
sent `{ ideType: "ANTIGRAVITY" }` — ideType as a bare string, with
platform and pluginType omitted entirely. 9router sends
`{ ideType: 9, platform: <os/arch enum>, pluginType: 2 }` — the field is
a protobuf-JSON int32 enum on the wire, not a string, and the API
apparently treats an incomplete/malformed identity as untrusted and
rejects it outright rather than degrading gracefully.
Fix: mirror 9router's LOAD_CODE_ASSIST_METADATA enum values and
platform-detection logic (darwin/linux/win32 x64/arm64) exactly.
A prior version of this function carried the opposite claim in a
comment ("Matches Antigravity-Manager quota.rs: only ideType — no
platform, LINUX is rejected"). That may have been true when written;
it directly contradicts today's live comparison, where the full-enum
shape (including a Linux platform value) succeeded from a Linux host.
Left a note pointing at this history in case it resurfaces.
Updated tests/unit/antigravity-headers.test.ts's metadata-shape
assertion accordingly — it previously asserted the broken string-only
shape as correct.
Validation
- New/updated unit test in tests/unit/antigravity-headers.test.ts
(6/6 passing) plus 54 usage-service + 25 oauth-provider tests whose
assertions already compare against this function's own output —
all passing.
- npx tsc --noEmit -p tsconfig.typecheck-core.json: 0 errors.
Note: in the specific deployment where this was found, the actual
403 root cause turned out to be a separate issue (a custom
ANTIGRAVITY_OAUTH_CLIENT_ID override pointing at a GCP project without
the private Cloud Code API enabled) — this metadata fix did not
resolve that deployment's error on its own, since Google's error
surfaces before the metadata shape would matter for a client-identity
rejection. It's included here because it's a real, independently
verified correctness bug (9router's identical live-working shape vs.
OmniRoute's incomplete one) that could still cause failures for
accounts using OmniRoute's default embedded OAuth client.
diegosouzapw
merged commit Aug 30, 2026
56dddfc
into
cheaper-inference:release/v3.8.51
14 of 15 checks passed
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…form/pluginType as numeric enums) (cheaper-inference#11969) Envia metadata completo do loadCodeAssist (ideType/platform/pluginType como enums numéricos) para o Antigravity, com teste de regressão atualizado. Validado no worktree combinado. Obrigado!
Witroch4
pushed a commit
to Witroch4/OmniRoute
that referenced
this pull request
Oct 24, 2026
…the wire
agy/antigravity connections presented a fingerprint no official client uses:
`Antigravity/4.2.0 (X11; Linux x86_64) Chrome/142 Electron/39` (4.2.0 came from
a third-party tool, Antigravity-Manager; the IDE never shipped it) plus
x-client-name, x-client-version, x-machine-id and x-vscode-sessionid on every
content request.
Ground truth (2026-10-24): the official `agy` 1.4.7 was run behind a local TLS
capture proxy that answered every request itself, so nothing reached Google.
All six daily-cloudcode-pa v1internal calls observed carried exactly:
User-Agent: antigravity/cli/1.4.7 (aidev_client; os_type=linux; arch=amd64; cl=1006008713; auth_method=consumer)
Authorization, Content-Type: application/json, Accept-Encoding: gzip
with loadCodeAssist metadata {"ideType":"ANTIGRAVITY"}; its Go OAuth calls use
Go-http-client/1.1. Neither the CLI nor the installed IDE 2.5.5 (language
server binary and JS) contains x-client-name/x-machine-id/x-vscode-sessionid
or an Electron UA. Both binaries embed the OAuth client id these connections
use, so the CLI identity matches their tokens. Upstream's cheaper-inference#8013/cheaper-inference#11969/cheaper-inference#16559
format (darwin/arm64 pinned, no cl=, numeric loadCodeAssist enums) also differs
from the real client, so it is deliberately not ported.
Changes:
- open-sse/config/antigravityCliClient.ts (leaf): the CLI build (version +
changelist pinned as a pair; ANTIGRAVITY_CLI_VERSION + ANTIGRAVITY_CLI_CHANGELIST
override only together), real host os_type/arch, Cloud Code headers in wire
order, OAuth token headers, loadCodeAssist metadata.
- Client profile "cli" (legacy stored "harness"/"sdk" read as cli) is now the
default; "ide" stays as an opt-in legacy profile with its version floor fixed
to the IDE's real ideVersion 2.5.5 (was 4.2.0).
- Every outbound path uses it: executor buildHeaders + per-attempt profile
headers (rebuilt to exactly the CLI set), project bootstrap (no longer
hard-defaults to "ide"; the executor passes the connection profile), token
refresh (executor + shared refreshGoogleToken for agy/antigravity), OAuth code
exchange + userinfo, model discovery, quota probes (loadCodeAssist now on the
daily host the CLI uses, not the sandbox), image generation, registry headers.
- Docs/.env.example: new vars documented; ANTIGRAVITY_USER_AGENT marked as not
applied by the Antigravity executor (the example had it active).
Known gaps (not header-level): undici fetch still adds accept-language and
sec-fetch-mode, and TLS/HTTP version (HTTP/1.1 vs the CLI's HTTP/2) differ.
The streamGenerateContent request itself was not captured (the CLI needs a
real model catalog to get there); it is inferred from the six uniform calls.
Tests: antigravity-cli-client (new) + 577 across 75 Antigravity/OAuth/usage/
discovery/image suites; translate-path golden regenerated (only the 6
Antigravity UA lines changed; os/arch normalized).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
loadCodeAssistandonboardUserboth returned 403 for every account on a livedeployment, even accounts that had completed Gemini Code Assist onboarding.
Root cause
Traced via a live log side-by-side (same Google account, same host) against the
sibling 9router project, which succeeds against the identical account:
getAntigravityLoadCodeAssistMetadata()sent{ ideType: "ANTIGRAVITY" }:ideTypeas a bare string,platformandpluginTypeomitted entirely.{ ideType: 9, platform: <os/arch enum>, pluginType: 2 }.The
metadatabody on this endpoint is protobuf-JSON-shaped:ideType/pluginTypeare int32 enums on the wire, not strings, and
platformis expected. Anincomplete/malformed client identity reads to Google's backend as untrusted and
gets rejected outright rather than degrading gracefully.
Fix
Mirror 9router's
LOAD_CODE_ASSIST_METADATAenum values and platform-detectionlogic (darwin/linux/win32 × x64/arm64) exactly:
A prior version of this function carried the opposite claim in a comment
("Matches Antigravity-Manager quota.rs: only ideType — no platform, LINUX is
rejected"). That may have been true when it was written; it directly
contradicts today's live comparison, where the full-enum shape (including a
Linux platform value) succeeded from a Linux host. Left a note pointing at
this history in the code in case it resurfaces — worth a second look if
anyone reports a regression specifically tied to Linux hosts.
Honest caveat
In the specific deployment where this was found, the actual 403 root cause
for that operator turned out to be unrelated: a custom
ANTIGRAVITY_OAUTH_CLIENT_IDoverride pointing at a GCP project without theprivate Cloud Code API enabled (Google's OAuth-client-identity check fails
before the request body/metadata shape would ever matter). This metadata fix
did not resolve that particular deployment's error on its own. It's
included here anyway because it's a real, independently verified correctness
bug — confirmed by a byte-for-byte comparison against 9router's identical,
live-working request shape — that could still cause failures for any account
using OmniRoute's default embedded OAuth client (not a custom override).
Validation
tests/unit/antigravity-headers.test.ts's metadata-shape assertion(previously asserted the broken string-only shape as correct) — 6/6 passing.
live output against this function — all still passing (no hardcoded
duplicate of the old shape anywhere else).
npx tsc --noEmit -p tsconfig.typecheck-core.json: 0 errors.I could not re-validate this specific fix against a live Google account
myself (no credentials here) — the live comparison that surfaced the bug was
done via the operator's production deployment logs, documented above.