Skip to content

fix(prebuilt): retry create_react_agent on MALFORMED_FUNCTION_CALL finish_reason#6986

Open
Saakshi Gupta (saakshigupta2002) wants to merge 1 commit intolangchain-ai:mainfrom
saakshigupta2002:fix/retry-malformed-function-call
Open

fix(prebuilt): retry create_react_agent on MALFORMED_FUNCTION_CALL finish_reason#6986
Saakshi Gupta (saakshigupta2002) wants to merge 1 commit intolangchain-ai:mainfrom
saakshigupta2002:fix/retry-malformed-function-call

Conversation

@saakshigupta2002

Description: When using create_react_agent with Google Gemini models, the agent silently terminates without making any tool calls when the LLM returns finish_reason: MALFORMED_FUNCTION_CALL. The should_continue conditional edge only checks for tool_calls presence on the AIMessage — when Gemini fails to produce valid JSON for a tool call, it returns an AIMessage with no tool_calls and sets finish_reason: MALFORMED_FUNCTION_CALL in response_metadata. The router sees no tool calls and routes to END, with no indication of the failure.

This PR adds detection of retryable finish_reason values in the should_continue router. When a retryable finish reason is detected (currently MALFORMED_FUNCTION_CALL), the agent logs a warning and routes back to the entrypoint node for a retry attempt. LangGraph's built-in recursion limit (default 25) prevents infinite retry loops.

Key changes:

  • Added _RETRYABLE_FINISH_REASONS module-level constant in chat_agent_executor.py — an extensible set of finish reasons that trigger retry
  • Modified should_continue to inspect response_metadata.finish_reason when no tool calls are present; retryable reasons route back to the agent entrypoint
  • Added entrypoint to agent_paths so the conditional edge accepts the retry target
  • Extended FakeToolCallingModel in tests with response_metadata_list support
  • Added 4 unit tests covering: retry on malformed call (v1/v2), no-retry on normal finish reason, warning log verification, and retry with pre_model_hook
  • Updated graph structure snapshots

Design rationale: retry (instead of raising) aligns with Google's own recommendation for handling MALFORMED_FUNCTION_CALL, and is backwards compatible since the only behavioral change is that previously-broken flows now recover instead of silently failing.

Closes #6574

Issue: #6574

Dependencies: None

…nish_reason

When using create_react_agent with Google Gemini, the agent would silently
terminate without making any tool calls when the LLM returned
finish_reason: MALFORMED_FUNCTION_CALL. The should_continue router only
checked for tool_calls presence and routed to END when none were found,
giving no indication of the failure.

This change detects retryable finish_reason values (currently
MALFORMED_FUNCTION_CALL) in the should_continue conditional edge and
routes back to the agent node for a retry attempt. A warning is logged
for observability. LangGraph's built-in recursion limit prevents
infinite retry loops.

Closes langchain-ai#6574
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant