{"record":{"id":"f4a96c10281a53be","repo":"apache/beam","slug":"project-and-location-must-be-none-if-api-key-is-set","errorCode":null,"errorMessage":"project and location must be None if api_key is set","messagePattern":"project and location must be None if api_key is set","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/inference/gemini_inference.py","lineNumber":190,"sourceCode":"    if max_batch_size is not None:\n      self._batching_kwargs[\"max_batch_size\"] = max_batch_size\n    if max_batch_duration_secs is not None:\n      self._batching_kwargs[\"max_batch_duration_secs\"] = max_batch_duration_secs\n    if max_batch_weight is not None:\n      self._batching_kwargs[\"max_batch_weight\"] = max_batch_weight\n    if element_size_fn is not None:\n      self._batching_kwargs['element_size_fn'] = element_size_fn\n    if batch_length_fn is not None:\n      self._batching_kwargs['length_fn'] = batch_length_fn\n    if batch_bucket_boundaries is not None:\n      self._batching_kwargs['bucket_boundaries'] = batch_bucket_boundaries\n\n    self.model_name = model_name\n    self.request_fn = request_fn\n\n    if api_key:\n      if project or location:\n        raise ValueError(\"project and location must be None if api_key is set\")\n      self.api_key = api_key\n      self.use_vertex = False\n    else:\n      if project is None or location is None:\n        raise ValueError(\n            \"project and location must both be provided if api_key is None\")\n      self.project = project\n      self.location = location\n      self.use_vertex = True\n\n    self.use_vertex_flex_api = use_vertex_flex_api\n\n    super().__init__(\n        namespace='GeminiModelHandler',\n        retry_filter=_retry_on_appropriate_service_error,\n        **kwargs)\n\n  def batch_elements_kwargs(self):","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/inference/gemini_inference.py#L172-L208","documentation":"Raised by the Gemini model handler __init__ when an api_key is provided together with a project and/or location. API-key authentication uses the Gemini Developer API, which does not take GCP project/location; those are only for Vertex AI.","triggerScenarios":"Constructing GeminiModelHandler(api_key='...', project='my-proj') or GeminiModelHandler(api_key='...', location='us-central1').","commonSituations":"Config templates that always populate project/location while also injecting an API key from a secret; switching between Vertex and Developer API auth without removing the other fields.","solutions":["Pass project=None and location=None when authenticating with api_key.","Remove api_key and supply both project and location if Vertex AI is the intended backend.","Read project/location from config conditionally: only when no api_key is present."],"exampleFix":"// before\nGeminiModelHandler(model_name='gemini-2.0-flash', api_key=key, project='my-proj', location='us-central1')\n// after\nGeminiModelHandler(model_name='gemini-2.0-flash', api_key=key)","handlingStrategy":"validation","validationCode":"if api_key and (project or location):\n    raise ValueError('drop project/location when using api_key')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make auth mode explicit: api_key XOR (project, location), never both.","Conditionally build constructor kwargs based on which credential is present."],"tags":["python","apache-beam","gemini","authentication"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}