{"record":{"id":"6d5dee8f2d6d0ecf","repo":"can1357/oh-my-pi","slug":"unknown-auth-broker-action-string-exhaustive","errorCode":null,"errorMessage":"Unknown auth-broker action: ${String(_exhaustive)}","messagePattern":"Unknown auth-broker action: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/auth-broker-cli.ts","lineNumber":967,"sourceCode":"\t\tcase \"logout\":\n\t\t\tawait runLogout(cmd.flags);\n\t\t\treturn;\n\t\tcase \"import\":\n\t\t\tawait runImport(cmd.flags);\n\t\t\treturn;\n\t\tcase \"migrate\":\n\t\t\tawait runMigrate(cmd.flags);\n\t\t\treturn;\n\t\tcase \"status\":\n\t\t\tawait runStatus(cmd.flags);\n\t\t\treturn;\n\t\tcase \"list\":\n\t\t\tawait runList(cmd.flags);\n\t\t\treturn;\n\t\tdefault: {\n\t\t\t// Exhaustive check.\n\t\t\tconst _exhaustive: never = cmd.action;\n\t\t\tthrow new Error(`Unknown auth-broker action: ${String(_exhaustive)}`);\n\t\t}\n\t}\n}\n\nexport { ACTIONS as AUTH_BROKER_ACTIONS };\n\n// Touch `$` so Bun's tree-shaker keeps the shell helper imported (used by future verbs).\nvoid $;\n","sourceCodeStart":949,"sourceCodeEnd":976,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/auth-broker-cli.ts#L949-L976","documentation":"The auth-broker CLI dispatches on a discriminated union of actions. The default branch is a TypeScript exhaustiveness check: `const _exhaustive: never = cmd.action` only compiles when every action is handled, and at runtime throws if an unhandled action string reaches dispatch. It is a defensive assertion against a bug in the CLI's own action parsing/extension, not user input.","triggerScenarios":"runAuthBrokerCommand receives a cmd.action value not covered by the switch — typically after adding a new action to the ACTIONS list without a corresponding case, or an internal parser bug producing an unexpected action.","commonSituations":"Developers extending the auth-broker CLI forget to add a switch case for the new action; stale build artifacts mixing old dispatcher with new command definitions.","solutions":["Add a `case \"<action>\"` branch handling the new action before the default exhaustive check.","Rebuild the project (bun install/build) so the dispatcher and action list are from the same build.","If you hit this as a user without modifying code, report it as a bug — it indicates an internal inconsistency."],"exampleFix":"// before\ncase \"list\":\n  await runList(cmd.flags);\n  return;\ndefault: { ... }\n// after\ncase \"list\":\n  await runList(cmd.flags);\n  return;\ncase \"rotate\":\n  await runRotate(cmd.flags);\n  return;\ndefault: { ... }","handlingStrategy":"type-guard","validationCode":"const KNOWN_ACTIONS = [\"migrate\",\"list\",...] as const;\nfunction isKnownAction(a: string): a is typeof KNOWN_ACTIONS[number] {\n  return (KNOWN_ACTIONS as readonly string[]).includes(a);\n}","typeGuard":"function isBrokerAction(a: unknown): a is AuthBrokerAction {\n  return typeof a === \"string\" && ACTIONS.includes(a as AuthBrokerAction);\n}","tryCatchPattern":"try {\n  await runAuthBrokerCommand(cmd);\n} catch (err) {\n  if (String(err).startsWith(\"Unknown auth-broker action\")) {\n    console.error(`Unsupported action \"${cmd.action}\". Valid: ${ACTIONS.join(\", \")}`);\n  }\n  throw err;\n}","preventionTips":["When adding an action, always add the switch case in the same commit","Rely on the `never` exhaustiveness check — never widen the union without a case","Run typecheck (bun check) before committing CLI changes"],"tags":["typescript","exhaustiveness","cli"],"backgroundTag":"unhandled-enum-case","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}