ruvnet/ruflo · error · Error

loop run requires a prompt unless --command is provided

Error message

loop run requires a prompt unless --command is provided

What it means

runCodexLoop() supports two modes: 'codex' (runs a Codex prompt each iteration) and 'command' (runs a shell command). In codex mode the prompt is the payload, so a missing or whitespace-only options.prompt with no options.command aborts immediately with this usage error before any state directory is created.

Source

Thrown at v3/@claude-flow/codex/src/loop/index.ts:127

    '',
    'Work autonomously for this iteration. Make concrete progress, run relevant checks, and stop before broad unrelated refactors.',
    `If the task is fully complete, create this marker file: ${state.untilFile}`,
    'If more work remains, leave the marker absent so the next loop iteration can continue.',
  ].join('\n');
}

export async function runCodexLoop(options: LoopRunOptions = {}): Promise<LoopState> {
  const projectPath = path.resolve(options.projectPath ?? process.cwd());
  const name = normalizeLoopName(options.name);
  const paths = resolveLoopPaths(projectPath, name, options.stateDir);
  const intervalSeconds = clampInteger(options.intervalSeconds ?? 270, 0, 86_400);
  const maxIterations = clampInteger(options.maxIterations ?? 10, 0, 100_000);
  const timeoutMs = clampInteger(options.timeoutMs ?? 30 * 60_000, 1_000, 24 * 60 * 60_000);
  const untilFile = path.resolve(projectPath, options.untilFile ?? paths.completePath);
  const mode: LoopState['mode'] = options.command ? 'command' : 'codex';

  if (mode === 'codex' && !options.prompt?.trim()) {
    throw new Error('loop run requires a prompt unless --command is provided');
  }

  await fs.ensureDir(paths.stateDir);
  await fs.remove(paths.stopPath);

  const startedAt = new Date().toISOString();
  const state: LoopState = {
    name,
    projectPath,
    mode,
    status: 'running',
    iteration: 0,
    maxIterations,
    intervalSeconds,
    startedAt,
    updatedAt: startedAt,
    untilFile,
  };

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Pass options.prompt with non-whitespace content when running in codex mode
  2. Or switch to command mode by providing options.command
  3. If building options dynamically, guard: if (!prompt?.trim() && !command) fail fast with your own message

Example fix

// before
await runCodexLoop({ name: 'lint-loop' }); // throws
// after
await runCodexLoop({ name: 'lint-loop', prompt: 'Run npm run lint and fix findings' });
// or command mode
await runCodexLoop({ name: 'lint-loop', command: 'npm run lint' });
Defensive patterns

Strategy: validation

Validate before calling

const prompt = options.prompt?.trim();
if (!prompt && !options.command) throw new Error('provide prompt or command');

Prevention

When it happens

Trigger: Calling runCodexLoop({}) or runCodexLoop({ name: 'x' }) with neither prompt nor command; CLI `loop run` invoked without --prompt and without --command; prompt passed as ' ' (whitespace only, fails the trim() check).

Common situations: Scripts build options dynamically and the prompt variable is undefined when a config field is misnamed (e.g. promptText vs prompt); CLI users assume the loop reads a default task from state; empty-string prompt from an env var.

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


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