ruvnet/ruflo · error

unattended swarm automation is disabled; set [swarm.automati

Error message

unattended swarm automation is disabled; set [swarm.automation] enabled = true

What it means

The dual-mode collaborative-execution command loads swarm-automation settings from .agents/config.toml in the current working directory via loadSwarmAutomationConfig(process.cwd()) and refuses to run when [swarm.automation] enabled is not true. This is a deliberate safety gate: unattended multi-worker automation (spawning Claude Code + Codex processes that write to your repo) must be opted into explicitly rather than running by default.

Source

Thrown at v3/@claude-flow/codex/src/dual-mode/cli.ts:63

      (val: string, acc: string[]) => { acc.push(val); return acc; },
      [] as string[],
    )
    .option('--parallel-workers', 'Run --worker specs in parallel instead of chaining them sequentially', false)
    .option('-c, --config <path>', 'Path to collaboration config JSON')
    .option('--task <description>', 'Task description for the swarm')
    .option('--max-concurrent <n>', 'Maximum concurrent workers (bounded by .agents/config.toml)')
    .option('--timeout <ms>', 'Worker timeout in milliseconds (bounded by .agents/config.toml)')
    .option('--namespace <name>', 'Shared memory namespace', 'collaboration')
    .action(async (templateArg: string | undefined, options) => {
      console.log(chalk.cyan('═══════════════════════════════════════════════════════════════'));
      console.log(chalk.cyan.bold('  DUAL-MODE COLLABORATIVE EXECUTION'));
      console.log(chalk.cyan('  Claude Code + Codex workers with shared memory'));
      console.log(chalk.cyan('═══════════════════════════════════════════════════════════════'));
      console.log();

      const automation = loadSwarmAutomationConfig(process.cwd());
      if (!automation.enabled) {
        throw new Error('unattended swarm automation is disabled; set [swarm.automation] enabled = true');
      }
      const requestedConcurrency = options.maxConcurrent
        ? parseInt(options.maxConcurrent, 10)
        : automation.maxConcurrent;
      const requestedTimeout = options.timeout
        ? parseInt(options.timeout, 10)
        : automation.agentTimeoutSeconds * 1000;
      const config: DualModeConfig = {
        projectPath: process.cwd(),
        maxConcurrent: Math.min(requestedConcurrency, automation.maxConcurrent),
        maxWriters: automation.maxWriters,
        worktreeIsolation: automation.worktreeIsolation,
        dependencyFailure: automation.dependencyFailure,
        timeout: Math.min(requestedTimeout, automation.agentTimeoutSeconds * 1000),
        maxOutputBytes: automation.maxOutputBytes,
        policyPreflight: true,
        sharedNamespace: options.namespace,
      };

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Add an explicit opt-in block to .agents/config.toml in the project root: `[swarm.automation]` then `enabled = true`.
  2. Run the command from the directory that contains .agents/config.toml (config is read from process.cwd()).
  3. While enabling, set the companion caps you actually want (maxConcurrent, maxWriters, agentTimeoutSeconds, worktreeIsolation) — the CLI clamps its flags to these values.
  4. If automation is intentionally forbidden in this repo, use attended workflows instead of the unattended dual-mode command.

Example fix

# before
$ npx @claude-flow/codex dual-mode run feature "add auth"
Error: unattended swarm automation is disabled; set [swarm.automation] enabled = true

# after — .agents/config.toml
[swarm.automation]
enabled = true
maxConcurrent = 4
maxWriters = 2
$ npx @claude-flow/codex dual-mode run feature "add auth"
Defensive patterns

Strategy: validation

Validate before calling

import { parse } from '@iarna/toml';
import { readFile } from 'node:fs/promises';
function automationEnabled(cwd: string): boolean {
  try {
    const t = parse(await readFile(join(cwd, '.agents/config.toml'), 'utf8')) as Record<string, unknown>;
    const a = t.swarm && (t.swarm as Record<string, unknown>).automation;
    return Boolean(a && (a as { enabled?: unknown }).enabled === true);
  } catch { return false; }
}
if (!automationEnabled(process.cwd())) {
  throw new Error('add [swarm.automation] enabled = true to .agents/config.toml first');
}

Try / catch

try {
  await runDualMode(args);
} catch (err) {
  if (err instanceof Error && err.message.includes('unattended swarm automation is disabled')) {
    throw new Error('opt-in required: add [swarm.automation] enabled=true to .agents/config.toml in the cwd you run from');
  }
  throw err;
}

Prevention

When it happens

Trigger: (1) Running the dual-mode run/collaborate command in a project where .agents/config.toml has no [swarm.automation] table or enabled = false (the default); (2) running it from a subdirectory that does not contain .agents/config.toml — the config is resolved from process.cwd(), not the package root; (3) a typo in the TOML key so it never parses as the automation table.

Common situations: Fresh clones where the gate has not been enabled; CI jobs invoking the command without first provisioning the config; developers running from a nested folder (src/, packages/x) of a monorepo where cwd lacks the file.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/2dc0c71dd4259f7a. Report an issue: GitHub.