fix(tools): write_file handler now rejects missing 'content'/'path' args instead of silently writing zero-byte files (#19096)
Under context pressure, frontier models sometimes emit tool calls with
required fields dropped. Previously _handle_write_file() used
args.get('content', '') which substituted an empty string for the missing
key, returned success with bytes_written=0, and created a zero-byte file
on disk. The model had no way to detect the failure.
Changes:
- Reject calls where 'path' is absent or not a non-empty string
- Reject calls where 'content' key is entirely absent (key-presence check,
not truthiness) — distinguishing a legitimately empty file from a dropped arg
- Reject calls where 'content' is a non-string type
- All error messages include guidance to re-emit the tool call or switch
to execute_code with hermes_tools.write_file() for large payloads
- Explicit empty string content (file truncation) continues to work
Regression tests added for all four cases: missing path, missing content,
explicit-empty content, and wrong content type.
Fixes #19096
This commit is contained in:
@@ -1097,7 +1097,25 @@ def _handle_read_file(args, **kw):
|
||||
|
||||
def _handle_write_file(args, **kw):
|
||||
tid = kw.get("task_id") or "default"
|
||||
return write_file_tool(path=args.get("path", ""), content=args.get("content", ""), task_id=tid)
|
||||
if not args.get("path") or not isinstance(args.get("path"), str):
|
||||
return tool_error(
|
||||
"write_file: missing required field 'path'. Re-emit the tool call with "
|
||||
"both 'path' and 'content' set."
|
||||
)
|
||||
if "content" not in args:
|
||||
return tool_error(
|
||||
"write_file: missing required field 'content'. The tool call included a "
|
||||
"path but no content argument — this is almost always a dropped-arg bug "
|
||||
"under context pressure. Re-emit the tool call with the full content "
|
||||
"payload, or use execute_code with hermes_tools.write_file() for very "
|
||||
"large files."
|
||||
)
|
||||
if not isinstance(args["content"], str):
|
||||
return tool_error(
|
||||
f"write_file: 'content' must be a string, got "
|
||||
f"{type(args['content']).__name__}."
|
||||
)
|
||||
return write_file_tool(path=args["path"], content=args["content"], task_id=tid)
|
||||
|
||||
|
||||
def _handle_patch(args, **kw):
|
||||
|
||||
Reference in New Issue
Block a user