{"record":{"id":"7ccc8136744d319f","repo":"ruvnet/ruflo","slug":"mode-must-be-legacy-observe-or-enforce","errorCode":null,"errorMessage":"mode must be legacy, observe, or enforce","messagePattern":"mode must be legacy, observe, or enforce","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/commands/policy.ts","lineNumber":55,"sourceCode":"export const policyCommand: Command = {\n  name: 'policy',\n  description: 'Agentic policy engine — evaluate actions, manage rules/approvals, and verify the decision ledger (ADR-324)',\n  options: [\n    { name: 'mode', type: 'string', description: 'Policy mode: legacy | observe | enforce' },\n    { name: 'project-root', type: 'string', description: 'Project root containing .claude-flow/policy' },\n  ],\n  async action(context: CommandContext): Promise<CommandResult> {\n    const args = (context as { args?: string[] }).args ?? [];\n    const flags = (context as { flags?: Record<string, unknown> }).flags ?? {};\n    const root = String(flags.projectRoot ?? process.cwd());\n    const operation = args[0] ?? 'status';\n    try {\n      if (operation === 'init' || operation === 'migrate') {\n        if (flags.mode || args[1]) requireInteractiveAdministrator();\n        const migration = await autoMigratePolicyStateIfNeeded(root);\n        const mode = String(flags.mode ?? args[1] ?? '') as PolicyState['mode'];\n        if (mode) {\n          if (!['legacy', 'observe', 'enforce'].includes(mode)) throw new Error('mode must be legacy, observe, or enforce');\n          await setPolicyMode(mode, root);\n        }\n        return print({ ...migration, state: loadPolicyState(root) });\n      }\n      if (operation === 'status') {\n        const state = loadPolicyState(root);\n        return print({\n          version: state.version,\n          mode: state.mode,\n          migratedFrom: state.migratedFrom,\n          rules: state.rules.length,\n          budgets: state.budgets.length,\n          approvals: state.approvals.length,\n          receipts: state.receipts.length,\n          ledger: await verifyPolicyLedger(root),\n        });\n      }\n      if (operation === 'evaluate') {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/commands/policy.ts#L37-L73","documentation":"Thrown when the policy mode argument is supplied but is not one of the three allowed modes (legacy, observe, enforce) defined by ADR-324. The modes form an ordered safety ramp from no-op (legacy) through logging-only (observe) to blocking (enforce); an unrecognized value is refused to prevent accidentally landing in an unintended posture.","triggerScenarios":"Calling `ruflo policy init --mode <bad>` or `policy init <bad>` (positional args[1]) with a typo such as `enforced`, `strict`, `prod`, `read-only`, or an empty-but-truthy token.","commonSituations":"Typos, guessing mode names from memory, copy-pasting a mode from an older/newer version of the docs, or trailing whitespace/quotes that survive into the comparison.","solutions":["Use exactly one of: legacy, observe, enforce (lowercase).","Run `ruflo policy status` to see the current mode and confirm accepted vocabulary.","Trim and lowercase the value if it comes from a variable: `mode=$(echo \"$MODE\" | tr '[:upper:]' '[:lower:]' | xargs)`."],"exampleFix":"// before\nruflo policy init --mode enforced\n// after\nruflo policy init --mode enforce","handlingStrategy":"validation","validationCode":"const POLICY_MODES = ['legacy', 'observe', 'enforce'] as const;\ntype PolicyMode = typeof POLICY_MODES[number];\nfunction asPolicyMode(v: string): PolicyMode {\n  if (!POLICY_MODES.includes(v as PolicyMode)) {\n    throw new Error(`mode must be one of ${POLICY_MODES.join(', ')}`);\n  }\n  return v as PolicyMode;\n}\nasPolicyMode((process.env.POLICY_MODE ?? '').toLowerCase());","typeGuard":"const isPolicyMode = (v: unknown): v is 'legacy'|'observe'|'enforce' =>\n  typeof v === 'string' && ['legacy','observe','enforce'].includes(v);","tryCatchPattern":"try {\n  await setPolicyMode(mode, root);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.startsWith('mode must be')) {\n    console.error('Allowed modes: legacy | observe | enforce');\n    process.exit(2);\n  }\n  throw e;\n}","preventionTips":["Lowercase and trim mode values from config before passing.","Drive mode from a typed enum in your config layer.","Run `policy status` to confirm the accepted vocabulary."],"tags":["cli","validation","policy","config"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}