Summary
Analysis of the last 24 hours of workflow runs found 2 errors (out of 2 total create_discussion calls — a 100% first-attempt failure rate) where agents called the create_discussion safe-output tool with the parameters wrapped under a key matching the tool name, instead of passing them flat. The MCP server rejected both with Invalid arguments: missing or empty 'title', 'body'.
This is a new pattern not previously seen by this optimizer (the historical database tracked only extra/wrong field errors such as pull_request_number, item_number, category_id, name). It was only detectable at the RPC layer — the final safeoutputs.jsonl shows only the successful retry, which is why earlier audits (e.g. 2026-06-04, the same two workflows) reported these calls as clean.
The per-tool description is correct, and both agents recovered on retry, so this is a tool-description / shared-prompt clarity issue, not a per-workflow prompt bug.
Error analysis details
Error pattern: parameters wrapped under the tool name
Occurrences: 2 times across 2 distinct workflows (both claude engine).
What agents did wrong — they sent the MCP tools/call arguments as:
{ "arguments": { "create_discussion": { "title": "...", "body": "...", "category": "..." } } }
instead of the flat, correct form:
{ "arguments": { "title": "...", "body": "...", "category": "..." } }
Because the top level has no title/body (only a nested create_discussion object, dropped by additionalProperties: false), the server responds:
calling "tools/call": Invalid arguments: missing or empty 'title', 'body'
Example — Daily Team Evolution Insights (Run §27039132770), from rpc-messages.jsonl:
- Request (rejected):
{"params":{"arguments":{"create_discussion":{"body":"> Daily anal...
- Response:
Invalid arguments: missing or empty 'title', 'body'
- Flat retry then hit a secondary 10 KB body-size limit (
'body' (12539 bytes)), recovered on a third attempt.
Example — Lockfile Statistics Analysis Agent (Run §27039242433):
- Request (rejected):
{"params":{"arguments":{"create_discussion":{"body":"### Sum...
- Response:
Invalid arguments: missing or empty 'title', 'body'
- Flat retry: succeeded.
Why this happened: the shared safe-output / reporting prompt teaches the NDJSON file-format example
{"noop": {"message": "No action needed: [brief explanation of what was analyzed and why]"}}
where the tool name is the wrapping key. Claude agents reasonably generalize this {tool_name: {params}} shape to the MCP tools/call arguments for create_discussion. Nothing in the tool description or shared docs tells the agent that MCP arguments must be flat (not wrapped under the tool name).
Current tool description
create_discussion schema from safe_outputs_tools.json
The schema is correct: required: [title, body], additionalProperties: false, plus optional category/secrecy/integrity. It simply does not address the wrapping mistake.
Root cause analysis
- The shared safe-output documentation presents tool output as
{"<tool_name>": { ...params }} (NDJSON file format), which is the wrong shape for MCP tools/call arguments, where params must be flat.
- Agents (Claude here) carry that
{tool_name: {params}} mental model into the actual MCP call for create_discussion.
- No tool description or shared note states that arguments are passed flat and must not be nested under the tool name.
Recommended improvements
A shared fix is preferred, since the mistake is not specific to create_discussion:
- Fix the misleading shared example. Change the canonical
noop snippet so it does not model the {tool_name: {params}} shape — present it as the flat tool arguments the agent should pass (call noop with {"message": "..."}), or clearly label the wrapped form as the NDJSON file format, not the MCP call format.
- Add a one-line note to the safe-output tool descriptions (ideally shared across all of them, mirroring the existing "alternate spellings are silently stripped" note):
Pass parameters directly as the tool arguments (e.g. title, body). Do NOT wrap them under a key named after the tool (e.g. {"create_discussion": {...}}).
Affected workflows
| Workflow |
Engine |
Run |
Outcome |
| Daily Team Evolution Insights |
claude |
§27039132770 |
wrapped → rejected → recovered (also hit 10 KB body limit) |
| Lockfile Statistics Analysis Agent |
claude |
§27039242433 |
wrapped → rejected → recovered |
Detection note
This pattern is invisible in safeoutputs.jsonl (which records only the successful flat retry). Detecting it requires inspecting mcp-logs/rpc-messages.jsonl for rpc_response events with a non-null error. The optimizer's daily process should sample RPC error responses, not just final emitted outputs — otherwise wrapped-then-recovered calls are silently missed (as on 2026-06-04 for these same two workflows).
Implementation checklist
References
- Tool schema:
pkg/workflow/js/safe_outputs_tools.json and actions/setup/js/safe_outputs_tools.json
- Misleading example source: shared safe-output / reporting prompt (
{"noop": {"message": "..."}})
- Run IDs with errors: §27039132770, §27039242433
Generated by ⚡ Daily Safe Output Tool Optimizer · agent 442.1 AIC · threat-detection 25.4 AIC · ◷
Summary
Analysis of the last 24 hours of workflow runs found 2 errors (out of 2 total
create_discussioncalls — a 100% first-attempt failure rate) where agents called thecreate_discussionsafe-output tool with the parameters wrapped under a key matching the tool name, instead of passing them flat. The MCP server rejected both withInvalid arguments: missing or empty 'title', 'body'.This is a new pattern not previously seen by this optimizer (the historical database tracked only extra/wrong field errors such as
pull_request_number,item_number,category_id,name). It was only detectable at the RPC layer — the finalsafeoutputs.jsonlshows only the successful retry, which is why earlier audits (e.g. 2026-06-04, the same two workflows) reported these calls as clean.The per-tool description is correct, and both agents recovered on retry, so this is a tool-description / shared-prompt clarity issue, not a per-workflow prompt bug.
Error analysis details
Error pattern: parameters wrapped under the tool name
Occurrences: 2 times across 2 distinct workflows (both
claudeengine).What agents did wrong — they sent the MCP
tools/callarguments as:{ "arguments": { "create_discussion": { "title": "...", "body": "...", "category": "..." } } }instead of the flat, correct form:
{ "arguments": { "title": "...", "body": "...", "category": "..." } }Because the top level has no
title/body(only a nestedcreate_discussionobject, dropped byadditionalProperties: false), the server responds:Example — Daily Team Evolution Insights (Run §27039132770), from
rpc-messages.jsonl:{"params":{"arguments":{"create_discussion":{"body":"> Daily anal...Invalid arguments: missing or empty 'title', 'body''body' (12539 bytes)), recovered on a third attempt.Example — Lockfile Statistics Analysis Agent (Run §27039242433):
{"params":{"arguments":{"create_discussion":{"body":"### Sum...Invalid arguments: missing or empty 'title', 'body'Why this happened: the shared safe-output / reporting prompt teaches the NDJSON file-format example
{"noop": {"message": "No action needed: [brief explanation of what was analyzed and why]"}}where the tool name is the wrapping key. Claude agents reasonably generalize this
{tool_name: {params}}shape to the MCPtools/callarguments forcreate_discussion. Nothing in the tool description or shared docs tells the agent that MCP arguments must be flat (not wrapped under the tool name).Current tool description
create_discussion schema from safe_outputs_tools.json
The schema is correct:
required: [title, body],additionalProperties: false, plus optionalcategory/secrecy/integrity. It simply does not address the wrapping mistake.Root cause analysis
{"<tool_name>": { ...params }}(NDJSON file format), which is the wrong shape for MCPtools/callarguments, where params must be flat.{tool_name: {params}}mental model into the actual MCP call forcreate_discussion.Recommended improvements
A shared fix is preferred, since the mistake is not specific to
create_discussion:noopsnippet so it does not model the{tool_name: {params}}shape — present it as the flat tool arguments the agent should pass (callnoopwith{"message": "..."}), or clearly label the wrapped form as the NDJSON file format, not the MCP call format.Affected workflows
Detection note
This pattern is invisible in
safeoutputs.jsonl(which records only the successful flat retry). Detecting it requires inspectingmcp-logs/rpc-messages.jsonlforrpc_responseevents with a non-nullerror. The optimizer's daily process should sample RPC error responses, not just final emitted outputs — otherwise wrapped-then-recovered calls are silently missed (as on 2026-06-04 for these same two workflows).Implementation checklist
noop/safe-output example to model flat MCP arguments (not{tool_name: {params}})create_discussion(ideally all safe-output tools) inpkg/workflow/js/safe_outputs_tools.jsonactions/setup/js/safe_outputs_tools.json(descriptions have drifted before — see [safeoutputs] #35579 description fixes never reached the runtime tool copy — all 4 stripped-field patterns recurred today (8× su [Content truncated due to length] #36000)make build/make recompile/make testcreate_discussionRPC rejections for 2-3 days to confirm the wrapping error rate dropsReferences
pkg/workflow/js/safe_outputs_tools.jsonandactions/setup/js/safe_outputs_tools.json{"noop": {"message": "..."}})