ruvnet/ruflo · error · Error
revoke requires an approval id
Error message
revoke requires an approval id
What it means
The `policy revoke` subcommand requires the approval id as its first positional argument; when args[1] is missing or empty, this error is thrown before revokePolicyApproval runs. The id identifies which approval entry to remove from the policy state.
Solutions
- List approvals first with `ruflo policy audit` and copy the exact approval id
- Pass it positionally: ruflo policy revoke <approvalId>
- Quote ids that contain special characters so the shell delivers them intact
Example fix
# before ruflo policy revoke # after ruflo policy revoke appr_20260818_001
Defensive patterns
Strategy: validation
Validate before calling
if (!approvalId || approvalId.trim() === '') {
const audit = await runPolicyCli(['policy', 'audit']); // read receipts to find the id
throw new Error('approval id required — pick one from `policy audit`');
}
await runPolicyCli(['policy', 'revoke', approvalId]); Type guard
function hasApprovalId(v: string | undefined): v is string {
return typeof v === 'string' && v.trim().length > 0;
} Prevention
- Always fetch the id from `policy audit` output rather than typing from memory
- Trim and assert non-empty ids in wrappers before invoking the CLI
- Remember position: `policy revoke <id>` — the id is args[1], after the operation
When it happens
Trigger: Running `ruflo policy revoke` with no argument, or passing an empty string '' (also falsy), or an invocation where a preceding flag consumed the value.
Common situations: Assuming revoke will prompt for the id; passing the id after another argument that shifts positions; quoting mistakes yielding an empty argv entry.
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
- requires a JSON argument
- approval issuance requires an authenticated human identity…
- must be valid JSON
- mode must be legacy, observe, or enforce
- policy administration requires an interactive local terminal
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/ad68b800be596117.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/commands/policy.ts:96
const rule = argJson<PolicyRule>(args[2], 'rule add');
await upsertPolicyRule(rule, root);
return print({ success: true, ruleId: rule.id });
}
if (operation === 'budget' && args[1] === 'set') {
requireInteractiveAdministrator();
const budget = argJson<BudgetLimit>(args[2], 'budget set');
await setPolicyBudget(budget, root);
return print({ success: true, budgetId: budget.id });
}
if (operation === 'approve') {
throw new Error(
'approval issuance requires an authenticated human identity adapter; '
+ 'the local TTY is not an identity credential',
);
}
if (operation === 'revoke') {
requireInteractiveAdministrator();
if (!args[1]) throw new Error('revoke requires an approval id');
return print({ success: await revokePolicyApproval(args[1], root), approvalId: args[1] });
}
if (operation === 'audit') {
const state = loadPolicyState(root);
return print({ receipts: state.receipts });
}
if (operation === 'verify') return print(await verifyPolicyLedger(root));
throw new Error(`unknown policy operation: ${operation}`);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
output.printError(message);
return { success: false, exitCode: 1, data: { error: message } };
}
},
examples: [
{ command: 'ruflo policy status', description: 'Show policy mode and ledger health' },
{ command: 'ruflo policy init --mode observe', description: 'Migrate an existing install without blocking legacy actions' },
{ command: 'ruflo policy budget set \'{"id":"daily-model","action":"model.call","maxCostUsd":10,"periodMs":86400000}\'', description: 'Set an atomic policy budget ceiling' },View on GitHub (pinned to fa13ee4ad6)