conductor-oss/conductor · error · IllegalArgumentException
Sub-agent name '${a.getName()}' in '${config.getName()}' is
Error message
Sub-agent name '${a.getName()}' in '${config.getName()}' is reserved: the coordinator uses DONE as its completion signal. Rename the agent. What it means
Thrown when a sub-agent in a multi-agent config has the name 'done' (case-insensitive). The coordinator workflow uses the literal string 'DONE' as its completion signal in a switch/decision node — a sub-agent named 'done' would clobber that switch case and make the completion signal unreachable, causing the workflow to loop forever or fail at runtime.
Source
Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/compiler/MultiAgentCompiler.java:2276
setInputs.put("is_transfer", ref(subRef + ".output.is_transfer"));
setInputs.put("transfer_to", ref(subRef + ".output.transfer_to"));
setInputs.put("_last_tool_results", ref(subRef + ".output.tool_results"));
setInputs.put("_agent_state", "${" + sCtxMergeRef + ".output.result}");
setVar.setInputParameters(setInputs);
caseTasks.add(setVar);
return caseTasks;
}
/**
* Reject sub-agent names that collide with the coordinator's reserved {@code DONE} decision. An
* agent named "done" (any case) would clobber the DONE switch case and make the coordinator's
* completion signal unreachable by construction.
*/
private void rejectReservedAgentNames(AgentConfig config, List<AgentConfig> agents) {
for (AgentConfig a : agents) {
if ("done".equalsIgnoreCase(a.getName())) {
throw new IllegalArgumentException(
"Sub-agent name '"
+ a.getName()
+ "' in '"
+ config.getName()
+ "' is reserved: the coordinator uses DONE as its completion "
+ "signal. Rename the agent.");
}
}
}
/**
* Build the coordinator routing system prompt shared by the handoff and router strategies.
*
* <p>Scope-awareness matters when the team is nested (e.g. a handoff team inside a swarm): the
* conversation seeded into the team contains the FULL original request, but the team may have
* been delegated only a slice of it (recorded as a {@code [<sender> -> <teamName>]: <note>}
* line by the swarm/handoff concat scripts). Without the scope rules below, a part of the
* request that no team member can handle makes DONE unreachable — the coordinator is forced toView on GitHub (pinned to cf7c3e4a8a)
Solutions
- Rename the sub-agent to anything other than 'done' (case-insensitive), e.g. 'finalizer', 'completer', or a domain-specific name.
- If the agent's role is to finalize output, use a descriptive name like 'summary_writer' or 'result_formatter' instead.
- Avoid any name that equals 'done' regardless of case.
Example fix
// before
agents=[{name: "done", description: "Finalizes the response"}]
// after
agents=[{name: "finalizer", description: "Finalizes the response"}] Defensive patterns
Strategy: validation
Validate before calling
void checkReservedNames(AgentConfig config) {
if (config.getAgents() != null) {
for (AgentConfig a : config.getAgents()) {
if ("done".equalsIgnoreCase(a.getName())) {
throw new IllegalArgumentException(
"Sub-agent name '" + a.getName() + "' is reserved (DONE signal). Rename it.");
}
}
}
} Try / catch
try {
compiler.compile(agentConfig);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("reserved")) {
// rename the offending agent from 'done' to something else
}
throw e;
} Prevention
- Never name any agent 'done' in any casing — it is a reserved coordinator keyword.
- Add a CI check that rejects agent definitions with reserved names.
When it happens
Trigger: Any AgentConfig whose getAgents() list contains an AgentConfig whose name, when compared case-insensitively to 'done', matches. For example names 'Done', 'DONE', 'done', or 'DoNe' all trigger this error.
Common situations: Naming an agent 'done' to indicate it handles completion or finalization tasks, without realizing the coordinator reserves that name. Also happens when agent names are auto-generated from task descriptions and one happens to produce 'done'.
Related errors
- SWARM handoff type must be on_tool_result, on_text_mention,
- SWARM handoff target must name a swarm agent: ${handoff.getT
- on_tool_result requires toolName and resultContains
- on_text_mention requires text
- on_condition requires a nonblank taskName
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/f0fbb5edb5784cfb.
Report an issue: GitHub.