fix(serve): a tool whose function is not an object answered 500 - #1710
Merged
JustVugg merged 1 commit intoSep 23, 2026
Merged
Conversation
{"type": "function", "function": "search"} on tools[] is the same
client slip JustVugg#1598 covered on tool_choice. generation_options already
has 400 "Tool function must be an object". The GLM and DeepSeek
declaration blocks did fn.items() first, so do_POST answered 500
"engine failed" for a request the engine never saw.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What happens
Writing the name where the object goes is the same client slip #1598
covered on
tool_choice. The server already has an answer for it:generation_options()raises400 "Tool function must be an object at index 0."It never runs on/v1/chat/completions, because the promptis rendered first:
That
AttributeErrorreachesdo_POST's catch-all, and the requestcomes back as a 5xx that OpenAI SDKs retry, against an engine that was
never asked anything.
Reach
generation_options)/v1/completions, any archgeneration_options)/v1/messagesis unaffected:anthropic_tools()builds its ownfunction object.
The change
Read the member, then check it, through one small helper, so the four
declaration blocks that share
fn.items()share the guard and theexisting 400 is what runs. A well-formed function object still renders
its name; that is asserted.
Verification
Full module and neighbours, on Windows (Python 3.11):
The
HTTPTestcases drive a realAPIServerover a socket, so what isasserted is the status the client sees.
AI-assisted (Grok)