AgentFixboard

MCP schema cleanup injects empty properties so nested arguments go out as {}

With MCP tools registered as direct function tools (tools.tool_search.enabled: "off"), an open nested object such as FastMCP call_tool(..., arguments: dict | None) is sent with "properties": {}. Calls then go out as {"name": "...", "arguments": {}} and the server rejects them with Missing required argument.

From GitHub

NousResearch/hermes-agent

Difficulty
Easy
Time
~5 min
Steps
2
Fixed in
—
Last checked

Not fixed upstream yet: the issue is open. Source: issue open. Last checked 2026-10-23.

Symptom

With MCP tools registered as direct function tools (tools.tool_search.enabled: "off"), an open nested object such as FastMCP call_tool(..., arguments: dict | None) is sent with "properties": {}. Calls then go out as {"name": "...", "arguments": {}} and the server rejects them with Missing required argument.

Evidence what you'll see

  • The server advertises arguments as {"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"default":null,...}. After _normalize_mcp_input_schema and sanitize_tool_schemas the model-facing schema adds "properties": {} and "required": [].
  • The report's offline probe prints arguments carries properties: True -> {}.
  • In the report's five-trial tool-call probe, the emitted schema sent {} in 5/5 runs. Removing only properties: {} sent {"title":"hello","body":"world"} in 5/5.

Why it happens

tools/mcp_tool_schema.py::_repair_object_shape and tools/schema_sanitizer.py::_sanitize_node both do if not isinstance(..., get("properties"), dict): ...["properties"] = {}. An open nested object with no declared fields then looks closed. With the default tool_search bridge the schema reaches the model as tool_describe text, so the empty map is masked.

Affected versions

Hermes 0.22.4, also present in 0.22.5 as far as the report can tell. Direct function tools with tools.tool_search.enabled: "off". Reproduced inside a 0.22.4 checkout venv with python repro.py --no-model for the schema half.

Fix steps

0 of 2 done

Your check marks stay in this browser only.

How to check it worked

  • The offline probe no longer prints properties: {} on the nested arguments object, and call_tool sends the filled arguments instead of {}.

If it still fails

  • The empty properties map is the trigger. required: [], nullable, and default alone did not produce {} in the report's separate measurements.
  • The linked issue does not name a release that stops injecting properties: {} on open nested objects.

Sources and credit

Summarized in our own words from these public reports. Credit goes to their authors.

Provided as is, without warranty. Try changes in a non-production environment and back up first. Security-related steps: verify against the official docs. Terms · Request removal or attribution change

Hit an error we don't cover? Submit it