{"record":{"id":"180ae2884dabc191","repo":"can1357/oh-my-pi","slug":"antigravity-credentials-missing-projectid","errorCode":null,"errorMessage":"Antigravity credentials missing projectId","messagePattern":"Antigravity credentials missing projectId","errorType":"exception","errorClass":"AIError.ConfigurationError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/registry/google-antigravity.ts","lineNumber":15,"sourceCode":"import * as AIError from \"../error\";\nimport type { OAuthCredentials, OAuthLoginCallbacks } from \"./oauth/types\";\nimport type { ProviderDefinition } from \"./types\";\n\nexport const googleAntigravityProvider = {\n\tid: \"google-antigravity\",\n\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\tlogin: async (cb: OAuthLoginCallbacks) => {\n\t\t// Lazy import: keep heavy OAuth flow modules out of the eager registry graph.\n\t\tconst { loginAntigravity } = await import(\"./oauth/google-antigravity\");\n\t\treturn loginAntigravity(cb);\n\t},\n\trefreshToken: async (credentials: OAuthCredentials) => {\n\t\tif (!credentials.projectId) {\n\t\t\tthrow new AIError.ConfigurationError(\"Antigravity credentials missing projectId\");\n\t\t}\n\t\tconst { refreshAntigravityToken } = await import(\"./oauth/google-antigravity\");\n\t\treturn refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t},\n\tcallbackPort: 51121,\n\tpasteCodeFlow: true,\n} as const satisfies ProviderDefinition;\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/registry/google-antigravity.ts#L1-L23","documentation":"Antigravity (Google) OAuth credentials must include a projectId because token refresh calls refreshAntigravityToken(refresh, projectId) — the project scopes the token exchange against Google's endpoints. When stored credentials lack projectId, the registry's refreshToken hook throws this ConfigurationError before attempting the refresh. The login flow normally populates projectId, so its absence means incomplete or legacy credentials.","triggerScenarios":"Calling the registry's refreshToken (or any path that triggers token refresh) with OAuthCredentials whose projectId field is null/undefined — typically credentials written by an older login flow, hand-crafted credentials, or a partially migrated auth.json.","commonSituations":"Credentials created before projectId became required; manually editing or truncating the stored auth file; syncing credentials across machines with different code versions; programmatically constructing OAuthCredentials without projectId.","solutions":["Delete the stored Antigravity credentials and re-run the login flow (loginAntigravity) so projectId is captured.","Manually add the correct projectId to the stored credentials object if you know it.","Check the stored auth file location (e.g. ~/.config omp auth state) for a missing or null projectId field.","Update the library/flow version so login and refresh agree on the credentials schema."],"exampleFix":"// before\nawait registry.refreshToken({ refresh: \"token\", projectId: undefined });\n// throws ConfigurationError\n// after (re-login to capture projectId)\nconst creds = await registry.login(callbacks); // includes projectId\nawait registry.refreshToken(creds);","handlingStrategy":"try-catch","validationCode":"// before triggering a refresh\nif (!credentials.projectId) {\n  await reloginAntigravity(); // recapture full credentials including projectId\n}","typeGuard":"function hasProjectId(c: OAuthCredentials): c is OAuthCredentials & { projectId: string } {\n  return typeof c.projectId === \"string\" && c.projectId.length > 0;\n}","tryCatchPattern":"try {\n  await registry.refreshToken(credentials);\n} catch (err) {\n  if (err instanceof AIError.ConfigurationError && /missing projectId/.test(err.message)) {\n    credentials = await registry.login(callbacks); // re-login to rebuild credentials\n    await registry.refreshToken(credentials);\n  } else throw err;\n}","preventionTips":["Re-login after upgrading library versions that change the credential schema.","Never hand-edit stored OAuth files; regenerate via the login flow.","Include projectId when constructing credentials programmatically.","Validate stored credentials (projectId present) at app startup."],"tags":["oauth","google","configuration","credentials","token-refresh"],"backgroundTag":"missing-credential-field","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}