{"record":{"id":"b1841a9658d425d2","repo":"BerriAI/litellm","slug":"the-response-was-blocked-by-vertexai-chunk","errorCode":null,"errorMessage":"The response was blocked by VertexAI. {chunk}","messagePattern":"The response was blocked by VertexAI\\. (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/streaming_handler.py","lineNumber":1320,"sourceCode":"                                        },\n                                        \"type\": \"function\",\n                                    }\n                                ],\n                            )\n                            _streaming_response: Final = StreamingChoices(delta=_delta_obj)\n                            _model_response: Final = ModelResponseStream()\n                            _model_response.choices = [_streaming_response]\n                            response_obj = {\"original_chunk\": _model_response}\n                        else:\n                            raise original_exception\n                    if (\n                        hasattr(chunk.candidates[0], \"finish_reason\")\n                        and chunk.candidates[0].finish_reason.name != \"FINISH_REASON_UNSPECIFIED\"\n                    ):  # every non-final chunk in vertex ai has this\n                        self.received_finish_reason = map_finish_reason(chunk.candidates[0].finish_reason.name)\n                except Exception:\n                    if chunk.candidates[0].finish_reason.name == \"SAFETY\":\n                        raise Exception(f\"The response was blocked by VertexAI. {chunk}\")\n            else:\n                completion_obj[\"content\"] = str(chunk)\n        elif self.custom_llm_provider == \"petals\":\n            if self.completion_stream is None or len(self.completion_stream) == 0:\n                if self.received_finish_reason is not None:\n                    raise StopIteration\n                else:\n                    self.received_finish_reason = \"stop\"\n            chunk_size = 30\n            stream = cast(Any, self.completion_stream)\n            new_chunk = stream[:chunk_size]\n            completion_obj[\"content\"] = new_chunk\n            self.completion_stream = stream[chunk_size:]\n        elif self.custom_llm_provider == \"palm\":\n            # fake streaming\n            response_obj = {}\n            if self.completion_stream is None or len(self.completion_stream) == 0:\n                if self.received_finish_reason is not None:","sourceCodeStart":1302,"sourceCodeEnd":1338,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/streaming_handler.py#L1302-L1338","documentation":"Vertex AI branch: when a stream chunk has no text (e.g. 'Part has no text') and the candidate's finish_reason is SAFETY, litellm raises this Exception embedding the raw proto chunk. It means Gemini/Vertex blocked the response with safety filters.","triggerScenarios":"Streaming a Vertex AI (Gemini) model where the prompt or partial generation trips safety filters; candidates carry finishReason=SAFETY and empty parts.","commonSituations":"Prompts touching violence/medical/self-harm topics; image+text prompts blocked by multimodal filters; default (unrelaxed) safety settings on newer Gemini models being stricter than expected.","solutions":["Adjust safety_settings per litellm/Vertex docs: set BLOCK_ONLY_HIGH or BLOCK_NONE for the tripped categories (subject to Google allowing relaxation).","Rephrase the prompt to avoid triggering categories; split sensitive steps into multiple calls.","Use a model version with different safety posture (e.g. latest Gemini versions).","Catch this exception and surface a user-facing 'content blocked' message instead of retrying — retrying the same input usually fails again."],"exampleFix":"# before\nresp = litellm.completion(model=\"vertex_ai/gemini-1.5-pro\", messages=msgs, stream=True)\n# after\nresp = litellm.completion(\n    model=\"vertex_ai/gemini-1.5-pro\", messages=msgs, stream=True,\n    safety_settings=[\n        {\"category\": \"HARM_CATEGORY_HARASSMENT\", \"threshold\": \"BLOCK_ONLY_HIGH\"},\n        {\"category\": \"HARM_CATEGORY_HATE_SPEECH\", \"threshold\": \"BLOCK_ONLY_HIGH\"},\n        {\"category\": \"HARM_CATEGORY_SEXUALLY_EXPLICIT\", \"threshold\": \"BLOCK_ONLY_HIGH\"},\n        {\"category\": \"HARM_CATEGORY_DANGEROUS_CONTENT\", \"threshold\": \"BLOCK_ONLY_HIGH\"},\n    ],\n)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    for part in stream:\n        ...\nexcept Exception as e:\n    if \"blocked by VertexAI\" in str(e):\n        return ContentBlockedResponse(reason=\"safety_filter\")  # do NOT retry same input\n    raise","preventionTips":["Set explicit safety_settings thresholds on every Vertex/Gemini call.","Design UX around safety blocks instead of retry loops; the same input usually re-blocks.","Log blocked prompts (redacted) to identify which category trips."],"tags":["vertex-ai","gemini","safety-filter","streaming"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}