Conversation
Bad Gemini keys never threw at client creation; failures only surfaced asynchronously via the Live session onerror/onclose callbacks, so the agent silently did nothing. Mirror the Fishjam credential check (FCE-2044): - gemini integration: add checkCredentials() and createClientAndValidate() (lightweight models.list() call; throws a clear error on a rejected key) - examples: validate the key at startup, before the server starts listening - docs: fix transcription README env var (GEMINI_API_TOKEN -> GEMINI_API_KEY), add the missing multimodal .env.example - add a unit test for checkCredentials Note: models.list() catches invalid/unauthorized/region-blocked keys, not the model-specific native-audio rejection (close code 1008 "reported as leaked" / 1011), which still surfaces only via the session callbacks.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a “fail fast” startup validation for Gemini API keys by introducing a lightweight credential check in the Gemini integration and updating the Gemini-based examples to validate the key before starting the server, reducing silent failures when keys are misconfigured.
Changes:
- Added
checkCredentials()(callsmodels.list()) andcreateClientAndValidate()to validate Gemini API keys up front. - Updated the transcription + multimodal examples to validate the Gemini key before constructing services / listening.
- Added/updated example docs and environment templates; added unit tests for
checkCredentials.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/js-server-sdk/tests/gemini.test.ts | Adds unit tests for the new Gemini credential check behavior (success + wrapped failure). |
| packages/js-server-sdk/src/integrations/gemini.ts | Introduces checkCredentials and createClientAndValidate, and documents that createClient is non-validating. |
| examples/transcription/src/service/transcription.ts | Refactors service construction to accept an already-created GoogleGenAI client. |
| examples/transcription/src/index.ts | Validates Gemini key at startup via createClientAndValidate. |
| examples/transcription/README.md | Fixes env var name and adds troubleshooting guidance for key validation/model-specific failures. |
| examples/multimodal/src/service/multimodal.ts | Refactors service construction to accept an already-created GoogleGenAI client. |
| examples/multimodal/src/index.ts | Validates Gemini key at startup via createClientAndValidate. |
| examples/multimodal/README.md | Adds troubleshooting guidance for key validation/model-specific failures. |
| examples/multimodal/.env.example | Adds missing env example file including GEMINI_API_KEY. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
models.list() can fail for non-auth reasons (network/DNS/transient), so the message no longer asserts the key was rejected; it names both causes and keeps the original error as cause. (Copilot review)
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.
Description
A bad Gemini API key never threw at client creation —
createClientis a synchronous wrapper aroundGoogleGenAIthat makes no network call. The key was only exercised atai.live.connect(), where auth/access failures surface asynchronously via the Live sessiononerror/onclosecallbacks. With the examples onlyconsole.error-ing those, the agent silently did nothing.This mirrors the Fishjam credential check from FCE-2044 (
FishjamClient.create/checkCredentials):packages/js-server-sdk/src/integrations/gemini.ts): addcheckCredentials(client)(one lightweightmodels.list()call; throws a clear error on a rejected key) and asynccreateClientAndValidate(options).createClientstays synchronous; JSDoc notes it does not validate.createClientAndValidate, before the server starts listening, so misconfiguration fails fast.GEMINI_API_TOKEN→GEMINI_API_KEY); add the missingexamples/multimodal/.env.example.checkCredentials(accept/reject, no live credentials).Note
models.list()catches invalid / unauthorized / wrong-project / region-blocked keys (the bulk of reports). It does not catch the model-specific native-audio rejection (close code 1008 "your API key was reported as leaked" / 1011), which still surfaces only via the session callbacks. That residual case is covered in the example READMEs' troubleshooting note.Motivation and Context
Closes FCE-3076 — "Some Gemini keys don't work with our SDK but don't throw." Reported during a hackathon; the silent failure made misconfigured keys hard to diagnose.
Documentation impact
Types of changes
not work as expected)