Skip to content

ChatVertexAI incompatible with pre-built ReAct agent when responses are blocked #886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
aabmass opened this issue Apr 23, 2025 · 1 comment · May be fixed by #929
Open

ChatVertexAI incompatible with pre-built ReAct agent when responses are blocked #886

aabmass opened this issue Apr 23, 2025 · 1 comment · May be fixed by #929

Comments

@aabmass
Copy link

aabmass commented Apr 23, 2025

I'm using LangGraph's pre-built ReAct agent create_react_agent() along with ChatVertexAI. Occasionally I was seeing 400 responses from VertexAI:

Retrying langchain_google_vertexai.chat_models._completion_with_retry.<locals>._completion_with_retry_inner in 4.0 seconds as it raised InvalidArgument: 400 Unable to submit request because it must include at least one parts field, which describes the prompt input.

Stacktrace

 Traceback (most recent call last):
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/google/api_core/grpc_helpers.py", line 76, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/grpc/_interceptor.py", line 277, in __call__
    response, ignored_call = self._with_call(
                             ~~~~~~~~~~~~~~~^
        request,
        ^^^^^^^^
    ...<4 lines>...
        compression=compression,
        ^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/grpc/_interceptor.py", line 332, in _with_call
    return call.result(), call
           ~~~~~~~~~~~^^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/grpc/_channel.py", line 440, in result
    raise self
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/grpc/_interceptor.py", line 315, in continuation
    response, call = self._thunk(new_method).with_call(
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        request,
        ^^^^^^^^
    ...<4 lines>...
        compression=new_compression,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/grpc/_channel.py", line 1198, in with_call
    return _end_unary_response_blocking(state, call, True, None)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/grpc/_channel.py", line 1006, in _end_unary_response_blocking
    raise _InactiveRpcError(state)  # pytype: disable=not-instantiable
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
	status = StatusCode.INVALID_ARGUMENT
	details = "Unable to submit request because it must include at least one parts field, which describes the prompt input. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini"
	debug_error_string = "UNKNOWN:Error received from peer ipv4:142.251.16.95:443 {grpc_message:"Unable to submit request because it must include at least one parts field, which describes the prompt input. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini", grpc_status:3, created_time:"2025-04-10T20:45:21.468704714+00:00"}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/opentelemetry/trace/__init__.py", line 587, in use_span
    yield span
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/opentelemetry/sdk/trace/__init__.py", line 1105, in start_as_current_span
    yield span
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/src/langgraph_chatbot_demo/langchain_history.py", line 215, in <module>
    res = app.invoke({"messages": [message]}, config=config)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langgraph/pregel/__init__.py", line 2669, in invoke
    for chunk in self.stream(
                 ~~~~~~~~~~~^
        input,
        ^^^^^^
    ...<6 lines>...
        **kwargs,
        ^^^^^^^^^
    ):
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langgraph/pregel/__init__.py", line 2323, in stream
    for _ in runner.tick(
             ~~~~~~~~~~~^
        loop.tasks.values(),
        ^^^^^^^^^^^^^^^^^^^^
    ...<2 lines>...
        get_waiter=get_waiter,
        ^^^^^^^^^^^^^^^^^^^^^^
    ):
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langgraph/pregel/runner.py", line 146, in tick
    run_with_retry(
    ~~~~~~~~~~~~~~^
        t,
        ^^
    ...<11 lines>...
        },
        ^^
    )
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langgraph/pregel/retry.py", line 40, in run_with_retry
    return task.proc.invoke(task.input, config)
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langgraph/utils/runnable.py", line 600, in invoke
    input = step.invoke(input, config, **kwargs)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langgraph/utils/runnable.py", line 357, in invoke
    ret = context.run(self.func, *args, **kwargs)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langgraph/prebuilt/chat_agent_executor.py", line 686, in call_model
    response = cast(AIMessage, model_runnable.invoke(state, config))
                               ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_core/runnables/base.py", line 3025, in invoke
    input = context.run(step.invoke, input, config)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_core/runnables/base.py", line 5358, in invoke
    return self.bound.invoke(
           ~~~~~~~~~~~~~~~~~^
        input,
        ^^^^^^
        self._merge_configs(config),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        **{**self.kwargs, **kwargs},
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_core/language_models/chat_models.py", line 307, in invoke
    self.generate_prompt(
    ~~~~~~~~~~~~~~~~~~~~^
        [self._convert_input(input)],
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<6 lines>...
        **kwargs,
        ^^^^^^^^^
    ).generations[0][0],
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_core/language_models/chat_models.py", line 843, in generate_prompt
    return self.generate(prompt_messages, stop=stop, callbacks=callbacks, **kwargs)
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_core/language_models/chat_models.py", line 683, in generate
    self._generate_with_cache(
    ~~~~~~~~~~~~~~~~~~~~~~~~~^
        m,
        ^^
    ...<2 lines>...
        **kwargs,
        ^^^^^^^^^
    )
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_core/language_models/chat_models.py", line 908, in _generate_with_cache
    result = self._generate(
        messages, stop=stop, run_manager=run_manager, **kwargs
    )
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_google_vertexai/chat_models.py", line 1310, in _generate
    return self._generate_gemini(
           ~~~~~~~~~~~~~~~~~~~~~^
        messages=messages,
        ^^^^^^^^^^^^^^^^^^
    ...<3 lines>...
        **kwargs,
        ^^^^^^^^^
    )
    ^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_google_vertexai/chat_models.py", line 1546, in _generate_gemini
    response = _completion_with_retry(
        self.prediction_client.generate_content,
    ...<5 lines>...
        **kwargs,
    )
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_google_vertexai/chat_models.py", line 636, in _completion_with_retry
    return _completion_with_retry_inner(
        generation_method,
        **params,
    )
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/tenacity/__init__.py", line 336, in wrapped_f
    return copy(f, *args, **kw)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/tenacity/__init__.py", line 475, in __call__
    do = self.iter(retry_state=retry_state)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/tenacity/__init__.py", line 376, in iter
    result = action(retry_state)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/tenacity/__init__.py", line 418, in exc_check
    raise retry_exc.reraise()
          ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/tenacity/__init__.py", line 185, in reraise
    raise self.last_attempt.result()
          ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/google/home/aaronabbott/.local/share/uv/python/cpython-3.13.1-linux-x86_64-gnu/lib/python3.13/concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/google/home/aaronabbott/.local/share/uv/python/cpython-3.13.1-linux-x86_64-gnu/lib/python3.13/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/tenacity/__init__.py", line 478, in __call__
    result = fn(*args, **kwargs)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/langchain_google_vertexai/chat_models.py", line 629, in _completion_with_retry_inner
    return generation_method(**kwargs)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/opentelemetry/instrumentation/vertexai/patch.py", line 168, in generate_content
    response = wrapped(*args, **kwargs)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/google/cloud/aiplatform_v1beta1/services/prediction_service/client.py", line 2396, in generate_content
    response = rpc(
        request,
    ...<2 lines>...
        metadata=metadata,
    )
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/google/api_core/gapic_v1/method.py", line 131, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/google/home/aaronabbott/repo/opentelemetry-python-contrib/instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/langgraph-chatbot-demo/.venv/lib/python3.13/site-packages/google/api_core/grpc_helpers.py", line 78, in error_remapped_callable
    raise exceptions.from_grpc_error(exc) from exc
google.api_core.exceptions.InvalidArgument: 400 Unable to submit request because it must include at least one parts field, which describes the prompt input. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini [detail: "[ORIGINAL ERROR] generic::invalid_argument: Unable to submit request because it must include at least one parts field, which describes the prompt input. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini [google.rpc.error_details_ext] { message: \"Unable to submit request because it must include at least one parts field, which describes the prompt input. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini\" } 525003295 { 1 { 1 { 1 { 1: \"blade:cloud.ai.nl.llm.proto.service.languagemodelservice-prod-us-central1\" 2: \"LanguageModelService\" 3: \"GenerateMultiModal\" } 2 { 1: 3 2: \"generic\" 3: \"Unable to submit request because it must include at least one parts field, which describes the prompt input. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini\" 5 { 1 { 2: 82012934 3 { 2: \"Unable to submit request because it must include at least one parts field, which describes the prompt input. Learn more: https://c...(length 1195)"
]
During task with name 'agent' and id 'e3877e3b-5f8b-c7c1-5e45-62f47f273458'

I debugged the problem and it happens If Gemini returns a blocked response (finishes with SAFETY reason) in an earlier interaction. LangGraph's checkpointer keeps a record of the blocked message which ChatVertexAI turns into an empty Content with no Parts in the RPC. Filtering out the blocked messages fixes the problem:

class PatchedChatVertexAI(ChatVertexAI):
    def _prepare_request_gemini(
        self, messages: list[BaseMessage], *args: Any, **kwargs: Any
    ) -> v1GenerateContentRequest | GenerateContentRequest:
        # Filter out any blocked messages with no content which can appear if you have a blocked
        # message from finish_reason SAFETY:
        messages = [
            message
            for message in messages
            if not message.response_metadata.get("is_blocked", False)
        ]
        return super()._prepare_request_gemini(messages, *args, **kwargs)

I'm happy to submit a fix.

@theo-davia
Copy link

theo-davia commented Apr 30, 2025

Hey @aabmass,
I encountered the same problem, thanks for finding the issue that was causing it !

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 a pull request may close this issue.

2 participants