fix: use loose null check and fix AttemptCompletionTool empty string rejection

- Change !== undefined to != null in NativeToolCallParser.ts (lines 452, 781)
  to also reject null values from malformed LLM JSON output
- Change !result to result == null in AttemptCompletionTool.execute() (line 72)
  to allow empty strings through instead of rejecting them as missing params
- Add test for null result rejection in NativeToolCallParser
This commit is contained in:
Roo Code 2026-02-21 02:48:51 +00:00
parent 9b3e7ba70a
commit 3630bf3505
3 changed files with 18 additions and 3 deletions

View file

@ -449,7 +449,7 @@ export class NativeToolCallParser {
break
case "attempt_completion":
if (partialArgs.result !== undefined) {
if (partialArgs.result != null) {
nativeArgs = { result: partialArgs.result }
}
break
@ -778,7 +778,7 @@ export class NativeToolCallParser {
break
case "attempt_completion":
if (args.result !== undefined) {
if (args.result != null) {
nativeArgs = { result: args.result } as NativeArgsFor<TName>
}
break

View file

@ -386,6 +386,21 @@ describe("NativeToolCallParser", () => {
}
})
it("should reject attempt_completion with null result", () => {
const toolCall = {
id: "toolu_completion_null",
name: "attempt_completion" as const,
arguments: JSON.stringify({
result: null,
}),
}
const result = NativeToolCallParser.parseToolCall(toolCall)
// null result should be rejected (no nativeArgs produced, parseToolCall returns null)
expect(result).toBeNull()
})
it("should handle streaming attempt_completion with empty string result", () => {
const id = "toolu_streaming_completion"
NativeToolCallParser.startStreamingToolCall(id, "attempt_completion")

View file

@ -69,7 +69,7 @@ export class AttemptCompletionTool extends BaseTool<"attempt_completion"> {
}
try {
if (!result) {
if (result == null) {
task.consecutiveMistakeCount++
task.recordToolError("attempt_completion")
pushToolResult(await task.sayAndCreateMissingParamError("attempt_completion", "result"))