[BUG] Workflow tool resolves agent({agentType}) against the session cwd's project registry, not the workflow script's own repo
What's Wrong?
When the Workflow tool runs a .mjs workflow script that is invoked by an absolute scriptPath living in repository B, and the session's current working directory is not inside repository B (an unrelated directory, or a different repo), then any agent({ agentType: '<custom>' }) call inside that workflow fails:
agent({agentType}): agent type '<custom>' not found.
Available agents: claude, Explore, general-purpose, Plan, statusline-setup
The custom agents defined in B's .claude/agents/*.md — sitting right next to the workflow script that spawns them — are never loaded. Only the built-in agent types are available, so every custom-agentType spawn in the workflow dies instantly (0 agents run).
The root cause is that the project agent registry is discovered by walking up from the session's cwd, but the Workflow tool does not augment that registry with agents discovered from the workflow script's own location when the script is invoked by absolute path. A workflow and the agents it spawns are authored together and live in the same repo, yet resolving them silently requires the invoking session's cwd to already be inside that repo — which invoking by absolute scriptPath is otherwise designed not to require.
This is a pre-merge/tooling trap: a repo whose workflows fan out to custom agents cannot be driven by absolute scriptPath from a session rooted anywhere else (e.g. a home directory, or a sibling repo). The generic finder/built-in agent angles that don't use a custom agentType succeed at full strength in the same run, so the failure is silent and partial rather than a hard stop.
What Should Happen?
A workflow's agent({ agentType }) should resolve custom agents defined in the workflow script's own repository — i.e. discover .claude/agents/ by walking up from the workflow scriptPath's directory — falling back to the session's cwd-derived registry. Then a workflow invoked by absolute scriptPath can spawn the custom agents that ship alongside it, regardless of where the invoking session is rooted.
At minimum, if resolution must stay bound to a single directory for a technical reason, the Workflow / Agent tool descriptions should state that custom agentType values only resolve against the session cwd's project registry — so the constraint is discoverable without characterizing it through failed spawns.
Error Messages/Logs
Error: agent({agentType}): agent type 'hf-ping' not found. Available agents: claude, Explore, general-purpose, Plan, statusline-setup
at K (/$bunfs/root/src/entrypoints/cli.js:10644:6569)
at processTicksAndRejections (native:7:39)
Steps to Reproduce
Fully self-contained minimal reproduction (no proprietary code):
- Create a "project" repo B at
/tmp/projwith a custom agent and a workflow that spawns it:
/tmp/proj/.claude/agents/hf-ping.md
``markdown``
---
name: hf-ping
description: Minimal test agent. Returns a fixed token.
model: haiku
tools:
---
You are a minimal test agent. Return JSON {"pong":"PONG-FROM-PROJECT-AGENT"} and nothing else.
/tmp/proj/.claude/workflows/hf-ping.mjs
``javascript``
export const meta = {
name: 'hf-ping',
description: 'Minimal repro workflow: spawns a project-local custom agentType.',
phases: [{ title: 'Ping' }],
}
phase('Ping')
const result = await agent(
'Return JSON {"pong":"PONG-FROM-PROJECT-AGENT"} and nothing else.',
{ label: 'ping', phase: 'Ping', agentType: 'hf-ping', model: 'haiku',
schema: { type: 'object', required: ['pong'], properties: { pong: { type: 'string' } } } },
)
log('workflow result: ' + JSON.stringify(result))
return result
- Create an unrelated empty directory
/tmp/outside(no.claude/).
- Control (works): from
/tmp/proj, run a session and use the Workflow tool with the relative path.claude/workflows/hf-ping.mjs. Thehf-pingagent resolves and the workflow returns{"pong":"PONG-FROM-PROJECT-AGENT"}.
- Bug (fails): from
/tmp/outside, run a session and use the Workflow tool with the absolute path/tmp/proj/.claude/workflows/hf-ping.mjs. The workflow dies immediately withagent type 'hf-ping' not found. Available agents: claude, Explore, general-purpose, Plan, statusline-setup— the custom agent that lives next to the workflow is never loaded, because the registry was built from the session cwd (/tmp/outside), not from the workflow script's repo (/tmp/proj).
The only difference between step 3 (passes) and step 4 (fails) is the session's cwd relative to the workflow script.
Claude Model
Not sure / Multiple models (repros with the workflow-spawned agent pinned to haiku)
Is this a regression?
I don't know
Last Working Version
(unknown — a related worktree-local variant of custom-agent resolution was fixed in an earlier release; this absolute-scriptPath-from-outside-cwd variant reproduces on the current version)
Claude Code Version
2.1.218 (Claude Code)
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Non-interactive/CI environment
Additional Information
- The custom agents live in the target repo and are tracked in git (byte-identical in every checkout); the failure is purely about which directory the registry is discovered from, not about the files being absent.
- Documented discovery behavior ("Project subagents are discovered by walking up from the current working directory") explains why this happens, but absolute-
scriptPathworkflow invocation is specifically a way to run a repo's workflow without the invoker's cwd being inside it — so the two features conflict. - Related but distinct existing issues (different mechanisms, same
area:agentssurface): #73387 (project agents deregister afterEnterWorktree/ not restored byExitWorktree), #77057 (project subagent not loaded in the desktop app), #68043 (agent registry cached at session start; newly-added agents don't register until restart — a copy of the agent into~/.claude/agents/mid-session does not help for exactly this reason). - Workaround in use: rewrite the workflow to spawn
agentType: 'general-purpose'and pass each agent's methodology to it by absolute file reference, so the persona reaches the agent as a file read rather than a resolved custom agent. This degrades the agents (loses theirtools/disallowedToolsrestrictions and system-prompt persona) and is not viable at scale.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗