Skip to content

[safeoutputs] Agents wrap params under the tool name when calling create_discussion (e.g. {"create_discussion": {...}}) -> "missing or empty t [Content truncated due to length] #37204

@github-actions

Description

@github-actions

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

  1. 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.
  2. Agents (Claude here) carry that {tool_name: {params}} mental model into the actual MCP call for create_discussion.
  3. 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:

  1. 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.
  2. 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 ·

  • expires on Jun 7, 2026, 9:30 PM UTC

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions