Skip to content

Fix googleai malformed function call crash#548

Merged
brainlid merged 2 commits into
brainlid:mainfrom
nelsonkopliku:google-ai-malformed-function-call
Jun 9, 2026
Merged

Fix googleai malformed function call crash#548
brainlid merged 2 commits into
brainlid:mainfrom
nelsonkopliku:google-ai-malformed-function-call

Conversation

@nelsonkopliku

Copy link
Copy Markdown
Contributor

When Gemini (tested with gemini-2.5-flash) cannot form a valid function call, it returns a candidate with the following shape:

%{
  "finishMessage" => "Some message...",
  "finishReason" => "MALFORMED_FUNCTION_CALL",
  "index" => 0
}

This in turn ends up in the last do_process_response match

def do_process_response(_model, other, _) do

and returns an {:error, %LangChainError{}} tuple and making the deltas reindexing reduction with a ** (KeyError) key :index not found in...

This PR makes sure the streaming does not crash and bubbles up the (first encoundered) error.

Caveats:

  • could be a model specific behaviour, newer models did not present the issue AFAICS
  • for completeness, the test covers for cases where the response body is a mix of successful MessageDeltas and error tuples, although IRL testing always manifested with a single entry list with the error tuple
  • depending on whether the "mix of successful MessageDeltas and error tuples" case is real, there might be different considerations to make like:
    • does it make sense to return the first encountered error? what about the others?
    • what about the non-errored MessageDeltas? would it be valuable to not "miss" in the best effort failure handling?
    • in case of many errored candidates, would it be useful to accumulate all of them in a single LangChainError struct that contains a list of many LangChainError?

I don't have evidences, yet, about other cases so I went for the simplest and less intrusive approach.

Copilot AI review requested due to automatic review settings May 13, 2026 10:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a crash in ChatGoogleAI streaming mode when Gemini returns candidates with finishReason: "MALFORMED_FUNCTION_CALL" (or other unexpected candidate shapes), ensuring streaming returns an error tuple instead of raising during delta reindexing.

Changes:

  • Detect {:error, %LangChainError{}} entries in streamed candidate deltas and return the first error early (avoids KeyError on :index during reindexing).
  • Extract the delta reindexing logic into a dedicated reindex_deltas/1 helper.
  • Add a test covering a streamed response body containing a mix of deltas and error tuples.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
lib/chat_models/chat_google_ai.ex Prevents streaming reduce/reindex from crashing when an error tuple appears among streamed candidates; refactors reindexing into a helper.
test/chat_models/chat_google_ai_test.exs Adds regression test ensuring streaming returns an error instead of crashing when malformed-function-call candidates appear.
Comments suppressed due to low confidence (1)

test/chat_models/chat_google_ai_test.exs:2036

  • Same as above: streamed %MessageDelta{} from ChatGoogleAI uses a single %ContentPart{} (or nil) for content, not a list. Aligning this fixture with actual streaming output will keep the test representative and reduce the risk of false confidence.
      delta2 = %LangChain.MessageDelta{
        content: [%LangChain.Message.ContentPart{type: :text, content: "Part 2"}],
        index: 0,
        role: :assistant,
        status: :incomplete
      }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/chat_models/chat_google_ai.ex
Comment thread test/chat_models/chat_google_ai_test.exs Outdated
@nelsonkopliku nelsonkopliku changed the title Fix googleai malformed function call Fix googleai malformed function call crash May 13, 2026
nelsonkopliku and others added 2 commits May 19, 2026 10:42
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@nelsonkopliku nelsonkopliku force-pushed the google-ai-malformed-function-call branch from 313774a to 535c2b0 Compare May 19, 2026 08:42
@nelsonkopliku

Copy link
Copy Markdown
Contributor Author

Hey @brainlid, first off thanks for this library and for accepting my previous, and first contribution!

I am wondering whether this PR is making sense for users of the lib from your perspective - I at least encountered the issue.

A note: I have another fix about google ai here nelsonkopliku#3.
I will wait for this one to go through before opening that one.

@brainlid

brainlid commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Thanks @nelsonkopliku!
❤️💛💙💜

@brainlid brainlid merged commit b1a2b1f into brainlid:main Jun 9, 2026
2 checks passed
@nelsonkopliku nelsonkopliku deleted the google-ai-malformed-function-call branch June 9, 2026 12:52
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 this pull request may close these issues.

3 participants