{"record":{"id":"a85d6adeaaf9a245","repo":"ruvnet/ruflo","slug":"at-least-one-agent-is-required","errorCode":null,"errorMessage":"at least one agent is required","messagePattern":"at least one agent is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/codex/src/worktrees/coordinator.ts","lineNumber":53,"sourceCode":"  readonly repoRoot: string;\n  readonly registryDir: string;\n  readonly worktreeBase: string;\n\n  constructor(repoRoot: string) {\n    this.repoRoot = resolve(repoRoot);\n    const top = git(this.repoRoot, ['rev-parse', '--show-toplevel']);\n    if (resolve(top) !== this.repoRoot) throw new Error(`repoRoot must be the git top-level: ${top}`);\n    this.registryDir = join(this.repoRoot, '.claude-flow', 'swarm', 'worktrees');\n    this.worktreeBase = join(dirname(this.repoRoot), '.ruflo-worktrees', basename(this.repoRoot));\n  }\n\n  prepare(\n    runId: string,\n    agents: Array<{ id: string; readOnly?: boolean }>,\n    options: { allowDirty?: boolean; baseRef?: string } = {},\n  ): WorktreeRunRecord {\n    assertId(runId, 'run id');\n    if (!agents.length) throw new Error('at least one agent is required');\n    const unique = new Set<string>();\n    for (const agent of agents) {\n      assertId(agent.id, 'agent id');\n      if (unique.has(agent.id)) throw new Error(`duplicate agent id: ${agent.id}`);\n      unique.add(agent.id);\n    }\n    const registryPath = this.registryPath(runId);\n    if (existsSync(registryPath)) return this.status(runId);\n    if (!options.allowDirty && git(this.repoRoot, ['status', '--porcelain']).length > 0) {\n      throw new Error('refusing to prepare writing worktrees from a dirty repository');\n    }\n\n    mkdirSync(this.registryDir, { recursive: true });\n    mkdirSync(join(this.worktreeBase, runId), { recursive: true });\n    const assignments: WorktreeAssignment[] = [];\n    try {\n      for (const agent of agents) {\n        const readOnly = agent.readOnly === true;","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/codex/src/worktrees/coordinator.ts#L35-L71","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconst agents = spawned.filter(a => a.role === 'coder'); // may be []\ncoordinator.prepare(runId, agents); // throws\n// after\nif (agents.length === 0) throw new Error('spawn produced no coder agents');\ncoordinator.prepare(runId, agents);","handlingStrategy":"validation","validationCode":"if (!Array.isArray(agents) || agents.length === 0) throw new Error('no agents to provision');","typeGuard":"function isNonEmptyAgentList(a: unknown): a is Array<{ id: string; readOnly?: boolean }> {\n  return Array.isArray(a) && a.length > 0 && a.every(x => typeof x?.id === 'string');\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["validation","worktrees","usage-error","swarm"],"backgroundTag":"missing-required-argument","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}