Repository navigation
vertexai.init(location=...) is ignored by genai.Client in _live_api_client, causing WebSocket 1008 for region-specific Live API models #5506
Description
PR: https://github.com/google/adk-python/pulls
Bug Report: vertexai.init(location=...) is ignored by genai.Client in _live_api_client, causing WebSocket 1008 for region-specific Live API models
🔴 Required Information
Describe the Bug:
vertexai.init(location=...) writes the location and project to google.cloud.aiplatform.initializer.global_config, but the genai.Client() constructed inside _live_api_client (in google_llm.py) never reads that state. Instead it falls back to the GOOGLE_CLOUD_LOCATION environment variable, which defaults to global.
Region-specific Live API models — such as gemini-live-2.5-flash-native-audio, which are only available in us-central1, us-east1, europe-west4, etc. — fail with a WebSocket 1008 Policy Violation because the Live API connection is silently routed to the global endpoint rather than the intended regional one. The two configuration systems (vertexai.init() and genai.Client()) are completely disconnected.
Steps to Reproduce:
- Install
google-adk(any version before the fix in PR fix: forward vertexai.init() location/project to genai.Client #4757) - In your application, call
vertexai.init(location='us-central1', project='my-gcp-project')to configure the regional endpoint - Initialize an ADK agent that uses a Live API model (e.g.,
gemini-live-2.5-flash-native-audioorgemini-live-2.5-flash) - Open a live/streaming session (e.g., bidirectional audio via
runner.run_live(...)) - Observe the WebSocket 1008 Policy Violation error — the connection attempts
globalinstead ofus-central1
Expected Behavior:
When vertexai.init(location='us-central1') is called before initializing ADK, the genai.Client() instantiated inside _live_api_client should read the location and project from initializer.global_config and use them explicitly. The Live API WebSocket connection should route to us-central1, successfully connecting to the region-specific model.
Observed Behavior:
The _live_api_client property in google_llm.py constructs genai.Client() without passing location or project, even when they were set via vertexai.init(). The client falls back to the GOOGLE_CLOUD_LOCATION env var (default: global), routing all Live API connections to the global endpoint. Region-specific models reject this with:
WebSocket connection closed: 1008 (Policy Violation)
The call never reaches the model. There is no warning that the configured location is being ignored.
Environment Details:
- ADK Library Version (
pip show google-adk): Reproducible on the currentmainbranch prior to PR fix: forward vertexai.init() location/project to genai.Client #4757 (e.g.,1.x.xreleases that do not include the fix) - Desktop OS: Linux
- Python Version (
python -V): 3.13.5
Model Information:
- Are you using LiteLLM: No
- Which model is being used:
gemini-live-2.5-flash-native-audio(any region-restricted Live API model)
🟡 Optional Information
Regression:
This is a pre-existing architectural gap — vertexai.init() and genai.Client() have never been connected in _live_api_client. It has not regressed from a previously working state; it has simply never worked for region-specific Live API models when using vertexai.init() for configuration.
Logs:
WebSocket connection closed: 1008 (Policy Violation)
The connection is made to the global Vertex AI endpoint, which rejects region-locked models. No ADK-level error is raised before the WebSocket closes.
Screenshots / Video:
N/A
Additional Context:
The root cause is in src/google/adk/models/google_llm.py, in the _live_api_client cached property:
# Before fix — location/project from vertexai.init() are never forwarded
@cached_property
def _live_api_client(self) -> Client:
return Client(
http_options=types.HttpOptions(
headers=self._tracking_headers(),
api_version=self._live_api_version,
),
)The fix (proposed in PR #4757) reads initializer.global_config.location and .project when GOOGLE_GENAI_USE_VERTEXAI is set, and passes them explicitly to Client():
# After fix
@cached_property
def _live_api_client(self) -> Client:
import os
from google.genai import Client
kwargs = {}
if os.environ.get('GOOGLE_GENAI_USE_VERTEXAI', '').lower() in ('1', 'true'):
from google.cloud.aiplatform import initializer
kwargs['location'] = initializer.global_config.location
kwargs['project'] = initializer.global_config.project
return Client(
**kwargs,
http_options=types.HttpOptions(
headers=self._tracking_headers(),
api_version=self._live_api_version,
base_url=self.base_url,
),
)The same gap exists in api_client and should be addressed there as well.
Workaround (until fix is merged): Explicitly set the GOOGLE_CLOUD_LOCATION environment variable to match the desired region (e.g., export GOOGLE_CLOUD_LOCATION=us-central1) in addition to calling vertexai.init(location='us-central1'). This is brittle and error-prone — it requires keeping two configuration sources in sync manually.
Minimal Reproduction Code:
import os
import vertexai
from google.adk.models.google_llm import Gemini
os.environ['GOOGLE_GENAI_USE_VERTEXAI'] = '1'
# Configure region via vertexai.init — the standard/documented approach
vertexai.init(location='us-central1', project='my-gcp-project')
# _live_api_client ignores the above; constructs genai.Client() with no location
# and falls back to 'global', which does not support gemini-live-2.5-flash
model = Gemini(model='gemini-live-2.5-flash')
# This will fail with WebSocket 1008 — connection routes to global, not us-central1
async def main():
from google.adk import Runner
from google.adk.agents import LlmAgent
from google.adk.sessions import InMemorySessionService
agent = LlmAgent(name='test', model='gemini-live-2.5-flash')
session_service = InMemorySessionService()
runner = Runner(agent=agent, app_name='test', session_service=session_service)
session = await session_service.create_session(app_name='test', user_id='u1')
# WebSocket 1008 raised here
async with runner.run_live(user_id='u1', session_id=session.id) as live:
await live.send_text('Hello')
import asyncio
asyncio.run(main())How often has this issue occurred?
- Always (100%) — any use of a region-specific Live API model with
vertexai.init(location=...)as the sole location configuration triggers this error every time.
Activity
surajksharma07 commentedon Apr 28, 2026
@civiliangame both _live_api_client and api_client in google_llm.py construct Client() without reading initializer.global_config, so vertexai.init(location=...) is quietly ignored and everything falls back to the global endpoint.
A local patch worth trying: under a GOOGLE_GENAI_USE_VERTEXAI guard in both cached properties, read global_config.location and .project and pass them explicitly into Client() — which is essentially what PR #4757 already proposes.
Could you apply that locally and confirm the WebSocket 1008 clears on your region-specific model?
civiliangame commentedon Apr 28, 2026
Hi, @surajksharma07 , I am the author of the PR #4757 . I am running that version locally and it works.
surajksharma07 commentedon Apr 28, 2026
@civiliangame Two things worth confirming before the PR progresses: first, does it also apply the global_config forwarding to api_client in addition to _live_api_client?
Both share the same gap as the issue notes.
Second, are global_config.location and .project null-guarded before being added to kwargs?
If GOOGLE_GENAI_USE_VERTEXAI=1 is set without a prior vertexai.init(), both values return None, and passing Client(location=None) explicitly behaves differently from omitting the kwarg entirely — which could silently regress callers who rely on env-var-based config.
Does the PR also include test coverage for the regional routing scenario?
surajksharma07 commentedon May 22, 2026
@civiliangame — closing this out for now since we haven't heard back after the questions I raised ~3 weeks ago about PR #4757 (null-guarding global_config.location/.project, whether api_client gets the same forwarding fix, and test coverage for the regional routing scenario).
PR #4757 is still the right path forward — once those three gaps are addressed, reviewers should be able to move it quickly.
Feel free to reopen or drop a note on the PR once you've had a chance to update it!