-
Notifications
You must be signed in to change notification settings - Fork 766
bug: Malformed tool input JSON silently replaced with empty dict, no logging #2051
Description
Description
In streaming.py, when a model returns invalid JSON as tool input, the ValueError is caught and the input is silently replaced with an empty dict {}. There is no log message or warning.
src/strands/event_loop/streaming.py, lines 279-282:
try:
current_tool_use["input"] = json.loads(current_tool_use["input"])
except ValueError:
current_tool_use["input"] = {}The tool then executes with empty arguments, fails with a missing-parameter error, and the model has no indication that its JSON was malformed. It retries the same broken JSON repeatedly.
This happens most often with smaller models (Ollama, llama.cpp, Mistral local) that produce truncated or syntactically invalid JSON for tool inputs.
Reproduction
Any model that returns invalid tool input JSON. Examples that trigger this:
{"query": "test(truncated by max_tokens mid-tool-call){query: test}(unquoted keys)- empty string
All silently become {}.
Suggested fix
Log a warning and return an informative error to the model instead of silently passing {} to the tool:
except ValueError:
logger.warning("Failed to parse tool input JSON for '%s': %s", current_tool_use.get("name"), current_tool_use["input"])
current_tool_use["input"] = {"_parse_error": f"Invalid JSON in tool input: {current_tool_use['input'][:200]}"}This way the tool can detect the parse error, and the model gets feedback that its JSON was malformed rather than thinking the tool itself is broken.
Happy to submit a PR for this.