This repository was archived by the owner on May 15, 2026. It is now read-only.
Fix: Prevent "Attempting to finalize unknown tool call" warning for GLM models - #11111
Draft
ghost wants to merge 1 commit into
Draft
Fix: Prevent "Attempting to finalize unknown tool call" warning for GLM models#11111ghost wants to merge 1 commit into
ghost wants to merge 1 commit into
Conversation
…nstarted tool calls - Add hasStarted check in processFinishReason() to only emit tool_call_end events for tool calls that have been properly started (received a name) - Add diagnostic warning when skipping unstarted tool calls - Add comprehensive tests for the hasStarted behavior with started, unstarted, and mixed scenarios - Fixes issue #11071 where GLM models send tool call IDs without names, causing synchronization issues between rawChunkTracker and streamingToolCalls This prevents the warning "Attempting to finalize unknown tool call" that appears when GLM models send incomplete tool call data (ID without name).
Author
Review complete. The implementation fix is correct and follows the existing pattern in
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
ghost
commented
Jan 30, 2026
Comment on lines
+434
to
+461
| it("should handle tool call that receives name in a separate chunk", () => { | ||
| // First chunk: ID only | ||
| NativeToolCallParser.processRawChunk({ | ||
| index: 0, | ||
| id: "call_delayed_name", | ||
| }) | ||
|
|
||
| // At this point, tool call is tracked but not started | ||
| let events = NativeToolCallParser.processFinishReason("tool_calls") | ||
| expect(events).toHaveLength(0) | ||
|
|
||
| // Clear state and try again with name | ||
| NativeToolCallParser.clearRawChunkState() | ||
|
|
||
| // Simulate proper sequence with name | ||
| NativeToolCallParser.processRawChunk({ | ||
| index: 0, | ||
| id: "call_delayed_name", | ||
| name: "read_file", | ||
| }) | ||
|
|
||
| events = NativeToolCallParser.processFinishReason("tool_calls") | ||
| expect(events).toHaveLength(1) | ||
| expect(events[0]).toEqual({ | ||
| type: "tool_call_end", | ||
| id: "call_delayed_name", | ||
| }) | ||
| }) |
Author
There was a problem hiding this comment.
This test doesn't actually test delayed name arrival. The clearRawChunkState() call on line 446 resets all state, so the second phase tests a completely independent scenario rather than a continuation. To properly test delayed name arrival, remove the clear and send two chunks in sequence:
Suggested change
| it("should handle tool call that receives name in a separate chunk", () => { | |
| // First chunk: ID only | |
| NativeToolCallParser.processRawChunk({ | |
| index: 0, | |
| id: "call_delayed_name", | |
| }) | |
| // At this point, tool call is tracked but not started | |
| let events = NativeToolCallParser.processFinishReason("tool_calls") | |
| expect(events).toHaveLength(0) | |
| // Clear state and try again with name | |
| NativeToolCallParser.clearRawChunkState() | |
| // Simulate proper sequence with name | |
| NativeToolCallParser.processRawChunk({ | |
| index: 0, | |
| id: "call_delayed_name", | |
| name: "read_file", | |
| }) | |
| events = NativeToolCallParser.processFinishReason("tool_calls") | |
| expect(events).toHaveLength(1) | |
| expect(events[0]).toEqual({ | |
| type: "tool_call_end", | |
| id: "call_delayed_name", | |
| }) | |
| }) | |
| it("should handle tool call that receives name in a separate chunk", () => { | |
| // First chunk: ID only | |
| NativeToolCallParser.processRawChunk({ | |
| index: 0, | |
| id: "call_delayed_name", | |
| }) | |
| // Second chunk: name arrives for the same index | |
| NativeToolCallParser.processRawChunk({ | |
| index: 0, | |
| name: "read_file", | |
| }) | |
| // Now the tool call should be started and receive end event | |
| const events = NativeToolCallParser.processFinishReason("tool_calls") | |
| expect(events).toHaveLength(1) | |
| expect(events[0]).toEqual({ | |
| type: "tool_call_end", | |
| id: "call_delayed_name", | |
| }) | |
| }) |
Fix it with Roo Code or mention @roomote and request a fix.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
This PR addresses issue #11071 by fixing the "Attempting to finalize unknown tool call" warning that appears when using GLM models via LM Studio or OpenAI-compatible endpoints.
Root Cause Analysis
The warning occurred due to a synchronization issue in
NativeToolCallParserbetween two tracking systems:rawChunkTracker- Tracks tool calls during raw chunk processing (keyed by stream index)streamingToolCalls- Tracks tool calls for argument accumulation (keyed by tool call ID)When GLM models send a tool call ID without a name (incomplete data), the tool call gets tracked in
rawChunkTrackerbut never "started" (notool_call_startevent emitted, not added tostreamingToolCalls).The
processFinishReason()method was emittingtool_call_endevents for ALL tracked tool calls, including those that were never started. This causedfinalizeStreamingToolCall()to fail with the warning.Changes Made
Added
hasStartedcheck inprocessFinishReason()tool_call_endevents for tool calls that have been properly started (have a name)finalizeRawChunks()methodComprehensive test coverage
Impact
This fix:
Testing
Added 5 new test cases covering various scenarios. Tests follow the existing pattern in the test suite.
Feedback welcome!
Important
Fixes warning in
NativeToolCallParserby ensuringtool_call_endevents are only emitted for started tool calls, with comprehensive test coverage added.hasStartedcheck inprocessFinishReason()inNativeToolCallParser.tsto emittool_call_endevents only for started tool calls.NativeToolCallParser.spec.tsfor started, unstarted, and mixed tool call scenarios.finish_reasonvalues and delayed name arrival.This description was created by
for b92cd76. You can customize this summary. It will automatically update as commits are pushed.