Skip to content

fix: normalize incomplete tool requests at extraction layer#1483

Open
gdeyoung wants to merge 1 commit intoagent0ai:mainfrom
gdeyoung:fix/extraction-normalize-tool-requests
Open

fix: normalize incomplete tool requests at extraction layer#1483
gdeyoung wants to merge 1 commit intoagent0ai:mainfrom
gdeyoung:fix/extraction-normalize-tool-requests

Conversation

@gdeyoung
Copy link
Copy Markdown
Contributor

@gdeyoung gdeyoung commented Apr 9, 2026

Problem

When LLMs output valid JSON with tool_name but missing or malformed tool_args, json_parse_dirty() returned the incomplete dict as-is. This causes ValueError: Tool request must have a tool_args (type dictionary) field crashes in validate_tool_request().

This is particularly common with:

  • Smaller models that omit tool_args when empty
  • Models that return tool_args as a JSON string instead of a dict
  • Models that use "tool" instead of "tool_name"

Root Cause

The extraction layer (json_parse_dirty()) passes through whatever DirtyJson parses without ensuring the result has the required fields for a tool request. The validation layer then crashes on incomplete input.

Fix

Normalize tool requests at the extraction layer in json_parse_dirty() before returning them:

  • Missing tool_args → defaults to {}
  • tool_args as string → converts to dict
  • tool_args as non-dict (number, null, etc.) → defaults to {}
  • "tool" key → normalized to "tool_name"

Non-tool requests (no tool_name or tool key) are left untouched.

Why This Approach

This fixes the root cause rather than band-aiding at the validation layer. Defense-in-depth (try/except at validation) is still good practice, but the extraction layer should guarantee a well-formed tool request structure.

Testing

Verified with 7 test scenarios:

  • ✅ Missing tool_args → defaults to {}
  • tool_args as string → converts to dict
  • tool_args as number → defaults to {}
  • "tool" key → normalized to "tool_name"
  • ✅ Non-tool request → untouched
  • ✅ Complete request → passes through unchanged
  • thoughts + tool_name but no tool_args → normalized

Related: #1458, #1466

When LLMs output valid JSON with tool_name but missing/malformed tool_args, json_parse_dirty() returned the incomplete dict as-is, causing ValueError crashes in validate_tool_request().

Root cause fix: normalize tool requests in json_parse_dirty() before returning them:

- Missing tool_args -> defaults to {}

- tool_args as string -> converts to dict

- tool_args as non-dict -> defaults to {}

- tool key -> normalized to tool_name

Non-tool requests are left untouched.

Related: agent0ai#1458, agent0ai#1466
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant