Skip to content

Conversation

@daniel-lxs
Copy link
Member

@daniel-lxs daniel-lxs commented Nov 14, 2025

Problem

When using native tool protocol, if read_file encountered an error (e.g., file not found), it would create two tool_result blocks with the same tool_call_id:

  1. handleError() internally calls pushToolResult() → tool_result Add options to always approve write and execute operations #1
  2. Code continues to final pushToolResult() with XML → tool_result Fix vscode compatibility issue #2

This violates the native protocol requirement of exactly one tool_result per tool_use_id, causing 400 errors on subsequent API calls.

Solution

Replace handleError() with task.say("error", ...) in error paths within ReadFileTool.

Agent still receives error details through the XML in the single final pushToolResult() call:

<file><path>nonexistent.txt</path><error>Error reading file: ENOENT</error></file>

Why This Doesn't Break Anything

Native Protocol

  • ✅ Only ONE pushToolResult() call = only ONE tool_result per tool_call_id
  • ✅ Agent receives error via XML: <error>Error reading file: ...</error>
  • ✅ User sees error via task.say()

XML Protocol

  • ✅ Only ONE text block with complete XML (cleaner than before with separate error blocks)
  • ✅ Agent receives error via XML (same as native)
  • ✅ User sees error via task.say() (same as before)

Both protocols: Agent error visibility is preserved through XML in the tool result.

Testing

  • ✅ All 44 tests passing in readFileTool.spec.ts
  • ✅ All pre-push tests passing (315 test files, 4069 tests)
  • ✅ Updated test to verify say() is called with error messages

… read_file

When read_file encountered errors (e.g., file not found), it would call
handleError() which internally calls pushToolResult(), then continue to
call pushToolResult() again with the final XML. In native protocol mode,
this created two tool_result blocks with the same tool_call_id, causing
400 errors on subsequent API calls.

This fix replaces handleError() with task.say() for error notifications.
The agent still receives error details through the XML in the single
final pushToolResult() call.

This change works for both protocols:
- Native: Only one tool_result per tool_call_id (fixes duplicate issue)
- XML: Only one text block with complete XML (cleaner than before)

Agent visibility preserved: Errors are included in the XML response
sent to the agent via pushToolResult().

Tests: All 44 tests passing. Updated test to verify say() is called.
@dosubot dosubot bot added size:S This PR changes 10-29 lines, ignoring generated files. bug Something isn't working labels Nov 14, 2025
@roomote
Copy link
Contributor

roomote bot commented Nov 14, 2025

Rooviewer Clock   See task on Roo Cloud

Review complete. No issues found.

The changes correctly address the duplicate tool_result issue in native protocol mode by replacing handleError() with task.say() in error paths. This ensures only one tool_result block per tool_call_id while preserving error visibility for both the agent (via XML) and the user (via task.say()).

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Review] in Roo Code Roadmap Nov 14, 2025
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Nov 14, 2025
@mrubens mrubens merged commit 1b19646 into main Nov 14, 2025
23 checks passed
@mrubens mrubens deleted the fix/read-file-duplicate-tool-results branch November 14, 2025 22:47
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Nov 14, 2025
@github-project-automation github-project-automation bot moved this from PR [Needs Review] to Done in Roo Code Roadmap Nov 14, 2025
mini2s added a commit to zgsm-ai/costrict that referenced this pull request Nov 17, 2025