Skip to content

fix(agents): trim whitespace from LLM tool call names to prevent lookup failures#27313

Closed
Sid-Qin wants to merge 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/27045-tool-name-whitespace
Closed

fix(agents): trim whitespace from LLM tool call names to prevent lookup failures#27313
Sid-Qin wants to merge 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/27045-tool-name-whitespace

Conversation

@Sid-Qin
Copy link
Contributor

@Sid-Qin Sid-Qin commented Feb 26, 2026

Summary

  • Problem: Some models return tool call names with leading/trailing whitespace (e.g. " read " instead of "read"), causing the agent loop's exact-match lookup to fail with "Tool not found" errors.
  • Why it matters: Tool calls intermittently fail, breaking agent functionality for affected models.
  • What changed: Added a wrapStreamFnTrimToolNames() stream wrapper that intercepts response events and trims toolCall content block names in-place before they reach the agent loop's tool dispatch.
  • What did NOT change (scope boundary): Tool registration, tool execution, and well-formed tool names (no whitespace) pass through unchanged with zero overhead.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

Tool calls with whitespace-padded names (e.g. " read ", " exec") now resolve correctly instead of failing with "Tool not found".

Security Impact (required)

  • New permissions/capabilities: None — only trims whitespace from tool names; does not alter tool execution or parameters
  • Auth/token changes: None
  • Data exposure risk: None

Testing

  • npx vitest run src/agents/pi-embedded-runner/run/attempt — 9 tests ✓

Rollback Plan

Revert the single commit. No migration or data changes involved.

…up failures

Some models return tool call names with leading/trailing whitespace
(e.g. " read " instead of "read").  The agent loop in pi-agent-core
uses an exact-match lookup (`tools.find(t => t.name === toolCall.name)`)
which fails on these names, producing "Tool  not found" errors.

Wrap the stream function to intercept response events and trim
toolCall content block names in-place before they reach the agent
loop's tool dispatch.

Closes openclaw#27045
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Fixes intermittent "Tool not found" errors by trimming whitespace from LLM-returned tool names before lookup. Some models return tool names like " read " or " exec" with leading/trailing whitespace, which causes exact-match failures in pi-agent-core's tools.find(t => t.name === toolCall.name).

Key changes:

  • src/agents/pi-embedded-runner/run/attempt.ts: Added wrapStreamFnTrimToolNames() stream wrapper that intercepts tool call events and trims whitespace from tool names in-place
  • Applied wrapper at line 881 (after anthropic payload logger wrapper if present)
  • src/agents/pi-tool-definition-adapter.ts: Cosmetic refactor extracting map result to variable (likely for debugging/future enhancement)

Implementation notes:

  • Wrapper correctly implements async iterator protocol with next(), return(), and throw() methods
  • Mutates tool call name blocks in-place; partial message objects are same references used by final result, so trimming propagates automatically
  • Only trims when trimmed !== original (zero overhead for well-formed names)
  • Follows same pattern as existing stream wrappers (anthropic-payload-log, cache-trace)

Safety:

  • Fully backward-compatible
  • Type guards prevent errors on unexpected block structures
  • Minimal performance overhead

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Score reflects targeted bug fix with minimal code surface area, full backward compatibility, established code patterns, passing tests, and no security implications. The fix directly addresses a real issue ([Bug]: Tool Names Not Trimmed, Causing "Tool Not Found" Errors #27045) with a simple, well-documented solution.
  • No files require special attention

Last reviewed commit: 5bc6e02

Copy link

@jeancloud007 jeancloud007 left a comment

Choose a reason for hiding this comment

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

LGTM. Defensive fix for LLM quirks - trimming tool names in the stream wrapper is clean and targeted. The in-place mutation approach avoids creating new objects while ensuring the trimmed names propagate to the done event. Good documentation.

@philipp-spiess
Copy link
Member

Superseded by #27094 (merged on main).

@philipp-spiess
Copy link
Member

Thanks @Sid-Qin for the excellent fix direction here.

We incorporated this live stream-wrapper approach into #27094 and merged the combined solution to main in 6b317b1.

Closing as superseded by #27094.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Tool Names Not Trimmed, Causing "Tool Not Found" Errors

3 participants