ruvnet/ruflo · error · Error

requires a JSON argument

Error message

${label} requires a JSON argument

What it means

policy.ts's argJson() helper throws when a policy subcommand that takes a JSON payload (rule add, budget set, evaluate) is invoked without its JSON positional argument. It is the CLI's missing-argument guard that runs before JSON.parse is ever attempted.

Solutions

  1. Append the JSON payload as a positional argument: ruflo policy rule add '{"id":"r1","effect":"deny"}'
  2. Copy the exact JSON shape from `ruflo policy --help` examples (budget set and evaluate examples are listed there)
  3. Single-quote the JSON on POSIX shells so it arrives as one argv entry

Example fix

# before
ruflo policy budget set

# after
ruflo policy budget set '{"id":"daily-model","action":"model.call","maxCostUsd":10,"periodMs":86400000}'
Defensive patterns

Strategy: validation

Validate before calling

const opsNeedingJson = ['rule add', 'budget set', 'evaluate'];
if (opsNeedingJson.includes(op) && !jsonPayload) {
  throw new Error(`op '${op}' needs a JSON positional argument`);
}
await runPolicyCli([...args, jsonPayload]);

Type guard

function hasJsonArg(v: string | undefined): v is string {
  return typeof v === 'string' && v.trim().length > 0;
}

Prevention

When it happens

Trigger: Running `ruflo policy rule add` with no third positional, `ruflo policy budget set` with no JSON, or `ruflo policy evaluate` with no request JSON — args[2] is undefined so the falsy check fires.

Common situations: Forgetting the JSON positional because most other subcommands pass data via flags; shell quoting that swallows the argument entirely (e.g. an empty '' which is also falsy).

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/27051ae525f9c10f. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/cli/src/commands/policy.ts:21

  PolicyRequest,
  PolicyRule,
  PolicyState,
} from '@claude-flow/security';
import type { Command, CommandContext, CommandResult } from '../types.js';
import { output } from '../output.js';
import {
  autoMigratePolicyStateIfNeeded,
  evaluatePolicyRequest,
  loadPolicyState,
  revokePolicyApproval,
  setPolicyBudget,
  setPolicyMode,
  upsertPolicyRule,
  verifyPolicyLedger,
} from '../services/policy-runtime.js';

function argJson<T>(value: string | undefined, label: string): T {
  if (!value) throw new Error(`${label} requires a JSON argument`);
  try { return JSON.parse(value) as T; }
  catch { throw new Error(`${label} must be valid JSON`); }
}

function print(data: unknown): CommandResult {
  output.writeln(JSON.stringify(data, null, 2));
  return { success: true, exitCode: 0, data };
}

function requireInteractiveAdministrator(): void {
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
    throw new Error('policy administration requires an interactive local terminal');
  }
}

export const policyCommand: Command = {
  name: 'policy',
  description: 'Agentic policy engine — evaluate actions, manage rules/approvals, and verify the decision ledger (ADR-324)',

View on GitHub (pinned to fa13ee4ad6)