{"repo":"NousResearch/hermes-agent","public_id":"56123","display_label":"Tool schema required field handling for strict OpenAI backends","summary":"These issues and fixes concern how the `required` field in tool/JSON schemas is handled when communicating with strict OpenAI-compatible backends, specifically whether it should be preserved as an empty array, injected when missing, or stripped when null/malformed to avoid HTTP 400 errors. The cluster centers on Moonshot/Kimi and delegate_task schemas, with overlapping but sometimes conflicting approaches to the fix.","subsystem":"agent","counts":{"members":21,"open_issues":1,"open_issues_distinct":1,"open_prs":3,"closed_issues":3,"merged_prs":3,"attempt_prs":14},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":68154},"resolution":{"state":"partially_resolved","by":"pr-68154,pr-112169,pr-115854"},"freshness":{"state":"verified","last_verified_at":"2026-09-19T17:17:00+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_PARTIAL","link_density":0.08780952380952381},"fix_edges":[{"issue_number":56123,"pr_number":115854,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true},{"issue_number":59386,"pr_number":112169,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true},{"issue_number":66835,"pr_number":68154,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true},{"issue_number":111684,"pr_number":112169,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true}],"members":[{"kind":"issue","number":56123,"title":"fix: schema_sanitizer strips required field causing HTTP 400 on strict OpenAI-compatible backends","url":null,"state":"closed"},{"kind":"issue","number":59386,"title":"[Bug]: `delegate_task` schema causes HTTP 400 / non-retryable crash on strict OpenAI-compatible backends","url":null,"state":"closed"},{"kind":"issue","number":60752,"title":"[Bug]: \"Tool schema with required: null causes HTTP 400 on strict OpenAI-compatible backends (e.g. arityflow.top) since v0.11+\"","url":null,"state":"open"},{"kind":"issue","number":66835,"title":"Moonshot/Kimi: tool schemas with empty properties missing \"required\" array cause HTTP 400","url":null,"state":"closed"},{"kind":"pr","number":56136,"title":"fix(tools): preserve empty required array instead of dropping key","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#20151","number":20151},{"kind":"pr","value":"#20151","number":20151}],"category":"superseded_by_pr","implication":"superseded"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":59416,"title":"fix: drop malformed required schema values","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"bd0affe5e5f723579df8902852f5d0c47795f355","number":0}],"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":59459,"title":"fix: keep empty required: [] instead of removing key (#59386)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"40b47b84e7","number":0},{"kind":"pr","value":"#112169","number":112169}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":59684,"title":"fix(delegate_task): mark tasks parameter nullable for strict OpenAI-compatible backends","url":null,"state":"closed","close_reason":{"category":"stale_abandoned","implication":"active"},"merged":false},{"kind":"pr","number":59926,"title":"fix(delegate): add default=[] to tasks schema for strict OpenAI backends (#59386)","url":null,"state":"open","close_reason":{"category":"uncategorized","implication":"needs_llm"},"merged":false},{"kind":"pr","number":60702,"title":"fix(schema): preserve empty required array in sanitizer and add additionalProperties to delegate_task (#59386)","url":null,"state":"closed","close_reason":{"category":"stale_abandoned","implication":"active"},"merged":false},{"kind":"pr","number":60755,"title":"fix(schema): drop null required from tool schemas","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#59416","number":59416},{"kind":"pr","value":"#59416","number":59416},{"kind":"pr","value":"#29329","number":29329},{"kind":"pr","value":"#59421","number":59421},{"kind":"pr","value":"#60752","number":60752}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":60766,"title":"fix: strip required:null from tool schemas for strict OpenAI-compatible backends","url":null,"state":"open","close_reason":{"refs":[{"kind":"pr","value":"#29329","number":29329},{"kind":"pr","value":"#60755","number":60755},{"kind":"pr","value":"#59416","number":59416}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":61204,"title":"fix(tools): strip required: null from tool schemas to prevent HTTP 400","url":null,"state":"open","close_reason":{"refs":[{"kind":"pr","value":"#59416","number":59416},{"kind":"pr","value":"#59416","number":59416},{"kind":"pr","value":"#29329","number":29329},{"kind":"pr","value":"#60766","number":60766},{"kind":"pr","value":"#29329","number":29329},{"kind":"pr","value":"#60702","number":60702}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":66849,"title":"fix(tools): keep empty required array instead of stripping it","url":null,"state":"closed","close_reason":{"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":66853,"title":"fix(moonshot): ensure required array is always present in tool schemas","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#66852","number":66852},{"kind":"pr","value":"#66852","number":66852}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":66855,"title":"fix(agent): inject empty required array on Moonshot object schemas (#66835)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#68154","number":68154}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":67430,"title":"fix(moonshot): inject required: [] on object schemas missing it","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#68154","number":68154},{"kind":"pr","value":"#66855","number":66855},{"kind":"pr","value":"#66852","number":66852}],"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":68154,"title":"fix(moonshot): inject required:[] on object schemas to fix kimi HTTP 400 (#66835)","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["agent/moonshot_schema.py","tests/agent/test_moonshot_schema.py","tests/agent/transports/test_chat_completions.py"]},{"kind":"pr","number":71220,"title":"fix(tools): keep empty required[] instead of dropping the key (#59386)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#59459","number":59459},{"kind":"pr","value":"#59459","number":59459}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":112169,"title":"fix(tools): zero-argument tool schemas keep `required: []` so strict OpenAI-compatible proxies stop 400ing (#111684, #59386, salvage #20151)","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["contributors/emails/[redacted:email]","tests/tools/test_schema_sanitizer.py","tools/schema_sanitizer.py"]},{"kind":"pr","number":115854,"title":"fix(mcp): MCP tool schemas keep required: [] so strict OpenAI-compatible backends stop rejecting requests (#56123, salvage #106288)","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["contributors/emails/[redacted:email]","tests/tools/test_mcp_tool.py","tests/tools/test_schema_sanitizer.py","tools/mcp_tool_schema.py","tools/schema_sanitizer.py"]}],"trust":{"default_tier":"verified","includes_suggested":false}}