[MODEL] Subagent ignored explicit forwarding contract and corrupted runtime arguments
Preflight Checklist
- [x] I have searched existing issues for similar behavior reports
- [x] This report does NOT contain sensitive information (API keys, passwords, etc.)
Type of Behavior Issue: Subagent behaved unexpectedly
What You Asked Claude to Do
I was using a custom Claude Code plugin/skill that defines a strict forwarding contract for a subagent which launches another runtime.
The contract explicitly required Claude to:
- Treat
--backgroundand--waitas Claude-side execution flags only - Strip those flags before invoking the downstream
taskcommand - If
task-resume-candidate --jsonreturnedavailable: true, ask the user exactly once whether to continue the current thread or start a new one - Not monitor progress, not tail logs, not fetch results, and not do follow-up work
- Return downstream stdout verbatim
Two representative prompts in the session were:
/codex:rescue --background --resume run rg for chip under /Users/mo/code with maximum coverage. Search recursively and case-insensitively. Do not use -F, -L, exclude globs, ignore rules, or --max-filesize. Save stderr/diagnostics to a log file. Save stdout results to a file named exactly <COUNT>.md, where <COUNT> is the final stdout line count. Report the count. Standby and monitor for further tasks after completion.
and
/codex:rescue --background audite the codex plugin implementation. find out why the 4 deployed today all failed. What is the specific cause and reason? Please fix it and prove it. Thank you.
What Claude Actually Did
Claude violated the explicit forwarding contract in multiple ways:
- It forwarded the execution flag
--backgroundinto the downstream task arguments instead of stripping it. - It skipped the required user choice after the resume-candidate check returned
available: true. - It monitored and tailed task output even though the prompt explicitly prohibited monitoring/follow-up.
- It later summarized a
/codex:resultpayload even though the instruction said to present the full output verbatim.
The clearest incorrect invocation was:
node ".../codex-companion.mjs" task --resume "--background" "run rg for chip under /Users/mo/code ..."
That should not happen. --background was an execution-mode flag for Claude Code, not natural-language task text.
In the second case, Claude first checked for resumability and got:
{
"available": true,
"candidate": {
"id": "task-mo19xn17-p3q2o1",
"status": "cancelled"
}
}
The prompt required an explicit user choice at that point, but Claude instead reasoned on its own that the prior thread was about a different task and silently injected --fresh.
Expected Behavior
Claude should have:
- Stripped
--backgroundand--waitbefore invoking the downstream task runtime - Preserved only the routing/runtime flags that the prompt said to preserve
- Asked the user exactly once when
task-resume-candidate --jsonreportedavailable: true - Avoided monitoring, log tailing, status/result polling, and follow-up work when the contract forbade that behavior
- Returned the downstream output verbatim when instructed to do so
Files Affected
No user project files were unintentionally modified in this report.
Unexpectedly accessed / used:
/private/tmp/claude-501/-Users-mo-code/.../tasks/*.output
custom plugin skill instructions for a forwarding-only subagent
Incorrect downstream invocation:
node ".../codex-companion.mjs" task --resume "--background" "run rg for chip ..."
Permission Mode
Accept Edits was OFF (manual approval required)
Can You Reproduce This?
Sometimes (intermittent)
Steps to Reproduce
- Define a custom Claude Code skill/subagent with a strict forwarding contract:
- strip
--backgroundand--wait - ask the user exactly once if a resumable thread is available
- do not monitor/follow up
- return downstream stdout verbatim
- Trigger the skill with a prompt that includes
--background --resume ... - Inspect the tool call transcript
- In some runs, Claude forwards
--backgroundas a positional downstream argument instead of stripping it - In another run where
task-resume-candidate --jsonreturnsavailable: true, Claude may skip the required user question and choose--freshor--resumeitself
Claude Model
Opus
Relevant Conversation
Representative transcript snippets:
Route this request to the `codex:codex-rescue` subagent.
...
- `--background` and `--wait` are execution flags for Claude Code. Do not forward them to `task`
...
- If that helper reports `available: true`, use `AskUserQuestion` exactly once
...
- Do not ask the subagent to inspect files, monitor progress, poll `/codex:status`, fetch `/codex:result`, call `/codex:cancel`, summarize output, or do follow-up work of its own.
Observed behavior:
node ".../codex-companion.mjs" task --resume "--background" "run rg for chip under /Users/mo/code ..."
There is a resumable thread available but it's about a different task ... I'll route directly ... with `--fresh`
ScheduleWakeup
wc -l /private/tmp/.../tasks/...output && tail -20 /private/tmp/.../tasks/...output
Impact
High - Significant unwanted changes
This is a control-plane nonconformity. Claude is not just producing a bad answer; it is rewriting execution/routing intent and issuing a different tool command than the instructions required. That can cause failed task routing, false resumes/fresh starts, and incorrect orchestration behavior.
Claude Code Version
2.1.110 (Claude Code)
Platform
Anthropic API
Additional Context
This looks important when Claude Code is being used as a controller for another runtime, or when a plugin intentionally relies on exact flag handling and exact compliance with deterministic operating rules.
In that setup, instruction-following is part of the control plane. If Claude can silently rewrite routing decisions or execution flags, the system is not trustworthy even if the downstream runtime is correct.
This issue is specifically about nonconformity to explicit operational instructions, not a generic quality complaint.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗