fix(mcp): don't inject phantom params for tools named required/properties - #56620
Open
golldyck wants to merge 1 commit into
Open
fix(mcp): don't inject phantom params for tools named required/properties#56620golldyck wants to merge 1 commit into
golldyck wants to merge 1 commit into
Conversation
…ties _normalize_mcp_input_schema's _repair_object_shape recursed into the properties map the same way it recurses into a schema node. When an MCP tool declared a parameter literally named "required" or "properties", the object-shape repair (fill missing type, add empty properties) fired on the properties map itself and stamped a "type": "object" plus an empty "properties" onto it. Those surfaced to the model as phantom parameters the server never declared, which the model could fill with junk args (and strict providers can 400 the malformed intermediate). Gate properties/patternProperties during descent so their keys are treated as user-facing parameter names, not JSON Schema meta-keywords — mirroring the existing gate in the sibling _rewrite_local_refs. All legitimate object-shape repairs (type inference, required pruning, nested coercion) are unchanged. Adds regression tests in tests/tools/test_mcp_tool.py.
13 tasks
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
Telegram API returns HTTP 400 when sent whitespace-only or empty text. Add a guard at the top of send() to silently succeed on blank content instead of crashing. Equivalent to OpenClaw NousResearch#56620.
liuchanchen
pushed a commit
to liuchanchen/hermes-agent
that referenced
this pull request
Jul 3, 2026
Telegram API returns HTTP 400 when sent whitespace-only or empty text. Add a guard at the top of send() to silently succeed on blank content instead of crashing. Equivalent to OpenClaw NousResearch#56620.
liuchanchen
pushed a commit
to liuchanchen/hermes-agent
that referenced
this pull request
Jul 3, 2026
Telegram API returns HTTP 400 when sent whitespace-only or empty text. Add a guard at the top of send() to silently succeed on blank content instead of crashing. Equivalent to OpenClaw NousResearch#56620.
habarmc1223-sudo
pushed a commit
to habarmc1223-sudo/hermes-agent-fluxmem
that referenced
this pull request
Jul 8, 2026
Telegram API returns HTTP 400 when sent whitespace-only or empty text. Add a guard at the top of send() to silently succeed on blank content instead of crashing. Equivalent to OpenClaw NousResearch#56620.
teknium1
reviewed
Jul 15, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for the focused regression coverage. The property-map premise is present on current main: tools/mcp_tool.py:4617-4633 recursively repairs a properties map and can inject type/properties when that map contains those names.
Problems
- The new guard only covers
propertiesandpatternProperties. Legacydefinitionsis rewritten to$defsbefore repair (tools/mcp_tool.py:4587,tools/mcp_tool.py:4648-4650), but$defsstill reaches the generic recursive branch. A$defsentry namedrequiredorpropertieswill be corrupted by the same object-shape logic. The shared sanitizer explicitly treats$defsas a name-to-schema map (tools/schema_sanitizer.py:308-312).
Suggested changes
- Include
$defsin the map-aware traversal and add a regression for a definition with a reserved name. The existing property-map tests should remain.
Automated hermes-sweeper review.
| repaired[k] = { | ||
| prop_name: _repair_object_shape(prop_schema) | ||
| for prop_name, prop_schema in v.items() | ||
| } |
Contributor
There was a problem hiding this comment.
Please extend this schema-map branch to $defs: _rewrite_local_refs has already converted legacy definitions to $defs before this repair runs, so a definition named required or properties still reaches the generic recursion and receives the same phantom entries.
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
Telegram API returns HTTP 400 when sent whitespace-only or empty text. Add a guard at the top of send() to silently succeed on blank content instead of crashing. Equivalent to OpenClaw NousResearch#56620.
jh1nresh
pushed a commit
to jh1nresh/hermes-agent
that referenced
this pull request
Aug 25, 2026
Telegram API returns HTTP 400 when sent whitespace-only or empty text. Add a guard at the top of send() to silently succeed on blank content instead of crashing. Equivalent to OpenClaw NousResearch#56620.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
_normalize_mcp_input_schema(via its inner_repair_object_shape) can inject phantom parameters into an MCP tool's schema when the tool declares a parameter literally namedrequiredorproperties._repair_object_shaperecurses into every dict the same way, including thepropertiesmap, whose keys are user-facing parameter names rather than JSON Schema meta-keywords. The object-shape repair right below it (fill a missingtype, ensure apropertiesdict exists) then fires on the properties map itself whenever it contains a key namedrequiredorproperties. That stamps a"type": "object"and an empty"properties"onto the map. Both then surface to the model as parameterstypeandpropertiesthat the MCP server never declared.Concrete reproduction (running the actual function):
propertieskeyspropertieskeys (before)["required"]["required", "type", "properties"]["properties"]["properties", "type"]config.properties = ["required"]["required", "type", "properties"](nested)["query"](normal)["query"](unaffected)The model can then fill those phantom params with junk arguments. Strict providers can also
400the malformed intermediate schema, because a"type": "object"string value ends up inside the properties map. That is the same failure mode the sibling_rewrite_local_refsdocstring already warns about.Root cause:
_rewrite_local_refswas deliberately fixed to special-casepropertiesandpatternPropertiesduring descent (see its docstring andtest_definitions_as_property_name_is_preserved), but the sibling_repair_object_shapewas overlooked. One traversal got fixed and the other was missed.Related Issue
Fixes #
Type of Change
Changes Made
tools/mcp_tool.py: in_repair_object_shape, gatepropertiesandpatternPropertiesduring descent so their keys are treated as user-facing parameter names (iterate the map, recurse only into each property's schema), mirroring the existing gate in_rewrite_local_refs. All legitimate repairs (type inference,requiredpruning, nested object coercion) are unchanged.tests/tools/test_mcp_tool.py: 3 regression tests (test_property_named_required_does_not_inject_phantom_params,test_property_named_properties_does_not_inject_phantom_type,test_property_named_required_is_preserved_when_nested).How to Test
scripts/run_tests.sh tests/tools/test_mcp_tool.py -q: 206 tests pass.tools/mcp_tool.pyhunk and rerun-k property_named. The 3 new tests fail, with phantomtypeandpropertiesappearing in the outputpropertiesmap. Restore the hunk and they pass.Checklist
Code
fix(mcp):)definitionsto$defsrename in_rewrite_local_refs; none touch_repair_object_shape)Documentation & Housekeeping
cli-config.yaml.example: N/ACONTRIBUTING.md/AGENTS.md: N/Ascripts/check-windows-footguns.pyclean)