Summary
Calling Skill(codex:rescue) programmatically from the main Claude Code
agent (not via the user-typed /codex:rescue slash command) triggers an
infinite recursion that hangs the session until manual cancellation. The
Codex CLI is never invoked.
Confirmed on plugin versions 1.0.2 and 1.0.3.
Repro
From the main agent (not the user's slash-command path):
Skill(codex:rescue, args: "<any rescue task>")
Observed behavior
- UI appears frozen; no Codex job is created.
- No entry under
~/.claude/plugins/data/codex-openai-codex/state/<project>/state.json.
- No log file under
~/.claude/plugins/data/codex-openai-codex/state/<project>/jobs/.
- After ~3+ minutes, user must cancel manually.
Root cause (from subagent fork log)
Timeline from ~/.claude/projects/<project>/<session>/subagents/agent-*.jsonl
(agentType: "general-purpose"):
T+0s fork subagent starts, loads rescue.md instructions + raw user request
T+2s "I'll check for a resumable rescue thread first"
T+3s Bash: codex-companion.mjs task-resume-candidate -> available: false ✓
T+15s ❌ Skill(codex:codex-rescue) attempted -> "Unknown skill: codex:codex-rescue"
T+20s ❌ recovery attempt: Skill(codex:rescue) called again (recurses into self)
T+217s hang; user cancels
Why:
commands/rescue.md frontmatter sets context: fork, so invocation
forks a general-purpose subagent and loads rescue.md body as its
instructions.
- The body instructs: "Route this request to the
codex:codex-rescue
subagent."
codex:codex-rescue is an agent (Agent tool's subagent_type),
not a skill (Skill tool).
- The forked general-purpose agent resolves the ambiguous wording by
trying Skill(codex:codex-rescue) → Unknown skill error.
- As a fallback, it re-invokes
Skill(codex:rescue) — which forks
itself again → infinite recursion → hang.
Why the slash command works but programmatic call doesn't
When the user types /codex:rescue, Claude Code's slash-command router
handles dispatch and does not fall into the "route to subagent" prose
resolution path. When the main agent calls Skill(codex:rescue), the
fork sees only the rescue.md body and has to interpret it — hence the
ambiguity.
Suggested fix
Change commands/rescue.md to name the transport explicitly, instead of
"route to subagent" prose. For example:
- Replace "Route this request to the
codex:codex-rescue subagent" with
an explicit instruction to use the Agent tool with
subagent_type: codex:codex-rescue, or
- Restrict
allowed-tools in rescue.md frontmatter to Agent only
(exclude Skill), which makes the recursive path impossible.
Workaround
Main agent calls the subagent directly:
Agent(subagent_type="codex:codex-rescue", prompt="...")
This skips the fork/resume-candidate check and invokes
node codex-companion.mjs task ... immediately. Users may see a
one-time permission prompt if Agent(codex:codex-rescue) is not in
their settings allow list.
Environment
- Claude Code on macOS (Darwin 25.2.0)
- Plugin versions tested: 1.0.2, 1.0.3
- Model: Claude Opus 4.6
Summary
Calling
Skill(codex:rescue)programmatically from the main Claude Codeagent (not via the user-typed
/codex:rescueslash command) triggers aninfinite recursion that hangs the session until manual cancellation. The
Codex CLI is never invoked.
Confirmed on plugin versions 1.0.2 and 1.0.3.
Repro
From the main agent (not the user's slash-command path):
Observed behavior
~/.claude/plugins/data/codex-openai-codex/state/<project>/state.json.~/.claude/plugins/data/codex-openai-codex/state/<project>/jobs/.Root cause (from subagent fork log)
Timeline from
~/.claude/projects/<project>/<session>/subagents/agent-*.jsonl(
agentType: "general-purpose"):Why:
commands/rescue.mdfrontmatter setscontext: fork, so invocationforks a
general-purposesubagent and loadsrescue.mdbody as itsinstructions.
codex:codex-rescuesubagent."
codex:codex-rescueis an agent (Agenttool'ssubagent_type),not a skill (
Skilltool).trying
Skill(codex:codex-rescue)→Unknown skillerror.Skill(codex:rescue)— which forksitself again → infinite recursion → hang.
Why the slash command works but programmatic call doesn't
When the user types
/codex:rescue, Claude Code's slash-command routerhandles dispatch and does not fall into the "route to subagent" prose
resolution path. When the main agent calls
Skill(codex:rescue), thefork sees only the rescue.md body and has to interpret it — hence the
ambiguity.
Suggested fix
Change
commands/rescue.mdto name the transport explicitly, instead of"route to subagent" prose. For example:
codex:codex-rescuesubagent" withan explicit instruction to use the
Agenttool withsubagent_type: codex:codex-rescue, orallowed-toolsin rescue.md frontmatter toAgentonly(exclude
Skill), which makes the recursive path impossible.Workaround
Main agent calls the subagent directly:
This skips the fork/resume-candidate check and invokes
node codex-companion.mjs task ...immediately. Users may see aone-time permission prompt if
Agent(codex:codex-rescue)is not intheir settings allow list.
Environment