ruvnet/ruflo · error · Error
at least one agent is required
Error message
at least one agent is required
What it means
CodexWorktreeCoordinator.prepare() provisions one worktree per agent; with an empty agents array there is nothing to provision and no run to record, so it fails fast with 'at least one agent is required' before touching git or the registry. Each agent id is additionally validated for uniqueness and SAFE_ID compliance.
Source
Thrown at v3/@claude-flow/codex/src/worktrees/coordinator.ts:53
readonly repoRoot: string;
readonly registryDir: string;
readonly worktreeBase: string;
constructor(repoRoot: string) {
this.repoRoot = resolve(repoRoot);
const top = git(this.repoRoot, ['rev-parse', '--show-toplevel']);
if (resolve(top) !== this.repoRoot) throw new Error(`repoRoot must be the git top-level: ${top}`);
this.registryDir = join(this.repoRoot, '.claude-flow', 'swarm', 'worktrees');
this.worktreeBase = join(dirname(this.repoRoot), '.ruflo-worktrees', basename(this.repoRoot));
}
prepare(
runId: string,
agents: Array<{ id: string; readOnly?: boolean }>,
options: { allowDirty?: boolean; baseRef?: string } = {},
): WorktreeRunRecord {
assertId(runId, 'run id');
if (!agents.length) throw new Error('at least one agent is required');
const unique = new Set<string>();
for (const agent of agents) {
assertId(agent.id, 'agent id');
if (unique.has(agent.id)) throw new Error(`duplicate agent id: ${agent.id}`);
unique.add(agent.id);
}
const registryPath = this.registryPath(runId);
if (existsSync(registryPath)) return this.status(runId);
if (!options.allowDirty && git(this.repoRoot, ['status', '--porcelain']).length > 0) {
throw new Error('refusing to prepare writing worktrees from a dirty repository');
}
mkdirSync(this.registryDir, { recursive: true });
mkdirSync(join(this.worktreeBase, runId), { recursive: true });
const assignments: WorktreeAssignment[] = [];
try {
for (const agent of agents) {
const readOnly = agent.readOnly === true;View on GitHub (pinned to fa13ee4ad6)
Solutions
- Check agents.length before calling prepare and surface a meaningful upstream error
- Fix the preceding step that should have produced agents (swarm spawn, config read, filter logic)
- Log the agent list right before the call so silent-empty cases are visible
Example fix
// before
const agents = spawned.filter(a => a.role === 'coder'); // may be []
coordinator.prepare(runId, agents); // throws
// after
if (agents.length === 0) throw new Error('spawn produced no coder agents');
coordinator.prepare(runId, agents); Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(agents) || agents.length === 0) throw new Error('no agents to provision'); Type guard
function isNonEmptyAgentList(a: unknown): a is Array<{ id: string; readOnly?: boolean }> {
return Array.isArray(a) && a.length > 0 && a.every(x => typeof x?.id === 'string');
} Prevention
- Assert a non-empty agent list where it is produced (after spawn/filter), not just where it is consumed
- Fail with context: report which upstream step returned zero agents
- Log the agent roster before provisioning worktrees
When it happens
Trigger: Calling prepare(runId, []) — typically because the callers agent list came back empty (a swarm spawn produced zero agents, a filter removed all entries, or a config mapped to an empty array).
Common situations: Programmatic orchestrators forward an agents array that a preceding spawn step populated; when spawn fails silently or filters over-prune (e.g. readOnly-only filtering), the array is empty and prepare is still called.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- You need to specify a parentId if this is not the first mess
- Cannot add a sibling to an empty conversation
- The sibling message is the root message, therefore we can't
- loop run requires a prompt unless --command is provided
- invalid ${label}: ${value}
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/a85d6adeaaf9a245.
Report an issue: GitHub.