ruvnet/ruflo · error · Error
revoke requires an approval id
Error message
revoke requires an approval id
What it means
Thrown by the revoke branch when args[1] (the approval identifier) is missing. Unlike approve, revoke is supported interactively, but it still needs the target approval id so the ledger records exactly which approval was withdrawn.
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 6b01dc5a68)
Solutions
- Look up the approval id first: `ruflo policy audit` prints the receipts list.
- Pass the id as the positional argument: `ruflo policy revoke <approvalId>`.
- Run from an interactive terminal — revoke also calls requireInteractiveAdministrator().
Example fix
// before ruflo policy revoke // after ruflo policy revoke appr_2024_08_12_abc
Defensive patterns
Strategy: validation
Validate before calling
function resolveApprovalId(arg?: string): string {
if (!arg) throw new Error('revoke requires an approval id');
return arg;
}
resolveApprovalId(process.argv[3]); // throws before reaching the CLI Type guard
const isApprovalId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;
Try / catch
try {
await revokePolicyApproval(id, root);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
if (msg === 'revoke requires an approval id') {
const ids = (await auditPolicy()).receipts.map(r => r.id);
console.error('Pass one of:', ids.join(', '));
process.exit(2);
}
throw e;
} Prevention
- List approvals with `policy audit` first.
- Pass the id positionally, not as a flag.
- Validate non-emptiness before invoking the CLI.
When it happens
Trigger: Running `ruflo policy revoke` with no second positional token, or with the id accidentally placed in a flag the command does not read.
Common situations: Forgetting the id, copy-pasting only the verb, or passing `--id <x>` (a flag) instead of the positional the command expects.
Related errors
- ${label} requires a JSON argument
- ${label} must be valid JSON
- mode must be legacy, observe, or enforce
- unknown policy operation: ${operation}
- Invalid target format: ${target}. Use agent:<id> or human:<i
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/ad68b800be596117.
Report an issue: GitHub.