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 to

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Rename the sub-agent to anything other than 'done' (case-insensitive), e.g. 'finalizer', 'completer', or a domain-specific name.
  2. If the agent's role is to finalize output, use a descriptive name like 'summary_writer' or 'result_formatter' instead.
  3. 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

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


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/f0fbb5edb5784cfb. Report an issue: GitHub.