Skip to content

FCE-3076 validate Gemini API key at startup to fail fast#283

Open
roznawsk wants to merge 2 commits into
mainfrom
fce-3076
Open

FCE-3076 validate Gemini API key at startup to fail fast#283
roznawsk wants to merge 2 commits into
mainfrom
fce-3076

Conversation

@roznawsk

Copy link
Copy Markdown
Member

Description

A bad Gemini API key never threw at client creation — createClient is a synchronous wrapper around GoogleGenAI that makes no network call. The key was only exercised at ai.live.connect(), where auth/access failures surface asynchronously via the Live session onerror/onclose callbacks. With the examples only console.error-ing those, the agent silently did nothing.

This mirrors the Fishjam credential check from FCE-2044 (FishjamClient.create / checkCredentials):

  • gemini integration (packages/js-server-sdk/src/integrations/gemini.ts): add checkCredentials(client) (one lightweight models.list() call; throws a clear error on a rejected key) and async createClientAndValidate(options). createClient stays synchronous; JSDoc notes it does not validate.
  • examples (transcription + multimodal): validate the key at startup via createClientAndValidate, before the server starts listening, so misconfiguration fails fast.
  • docs: fix transcription README env var (GEMINI_API_TOKENGEMINI_API_KEY); add the missing examples/multimodal/.env.example.
  • test: unit test for 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

  • Documentation update required
  • Documentation updated in another PR — public docs site update handed off separately
  • No documentation update required

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to
    not work as expected)

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.
@linear

linear Bot commented Jun 26, 2026

Copy link
Copy Markdown

FCE-3076

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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() (calls models.list()) and createClientAndValidate() 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.

Comment thread packages/js-server-sdk/src/integrations/gemini.ts
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)
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.

2 participants