{"record":{"id":"35561d649224db6b","repo":"can1357/oh-my-pi","slug":"canary-and-stable-are-mutually-exclusive","errorCode":null,"errorMessage":"--canary and --stable are mutually exclusive","messagePattern":"--canary and --stable are mutually exclusive","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/coding-agent/src/cli/update-cli.ts","lineNumber":382,"sourceCode":"\tbackupPath: string;\n\texpectedVersion: string;\n\tverifyInstalledVersion: (expectedVersion: string) => Promise<InstalledVersionVerification>;\n}\n\n/**\n * Parse update subcommand arguments.\n * Returns undefined if not an update command.\n */\nexport function parseUpdateArgs(\n\targs: string[],\n): { force: boolean; check: boolean; plugins: boolean; channel?: UpdateChannel } | undefined {\n\tif (args.length === 0 || args[0] !== \"update\") {\n\t\treturn undefined;\n\t}\n\n\tconst canary = args.includes(\"--canary\");\n\tconst stable = args.includes(\"--stable\");\n\tif (canary && stable) throw new Error(\"--canary and --stable are mutually exclusive\");\n\n\treturn {\n\t\tforce: args.includes(\"--force\") || args.includes(\"-f\"),\n\t\tcheck: args.includes(\"--check\") || args.includes(\"-c\"),\n\t\tplugins: args.includes(\"--plugins\") || args.includes(\"-l\"),\n\t\tchannel: canary ? \"canary\" : stable ? \"stable\" : undefined,\n\t};\n}\n\nasync function getBunGlobalBinDir(): Promise<string | undefined> {\n\tif (!$which(\"bun\")) return undefined;\n\ttry {\n\t\tconst result = await $`bun pm bin -g`.quiet().nothrow();\n\t\tif (result.exitCode !== 0) return undefined;\n\t\tconst output = result.text().trim();\n\t\treturn output.length > 0 ? output : undefined;\n\t} catch {\n\t\treturn undefined;","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/update-cli.ts#L364-L400","documentation":"Argument-validation error thrown by parseUpdateArgs when both --canary and --stable are passed to `omp update`. The two flags select mutually exclusive release channels (bleeding-edge vs latest stable), so the updater refuses to guess and fails fast before touching the network.","triggerScenarios":"`omp update --canary --stable`, `omp update -f --canary --stable`, or scripts/aliases that append a channel flag to a command line that already contains the other.","commonSituations":"A shell alias like `alias oup='omp update --canary'` combined with a habit of typing `... --stable`; documentation snippets pasted together; scripted update jobs where the channel is interpolated twice.","solutions":["Pick one channel: run `omp update --canary` OR `omp update --stable`, not both.","Inspect aliases/functions (`type omp` / `alias | grep omp`) and remove a baked-in channel flag if it collides with the one you pass.","Use plain `omp update` with no channel flag to keep the default channel."],"exampleFix":"// before\n$ omp update --canary --stable\n// Error: --canary and --stable are mutually exclusive\n// after\n$ omp update --stable","handlingStrategy":"validation","validationCode":"const canary = args.includes(\"--canary\");\nconst stable = args.includes(\"--stable\");\nif (canary && stable) throw new Error(\"--canary and --stable are mutually exclusive\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check shell aliases for baked-in channel flags before adding your own","Pass at most one channel flag","Omit channel flags entirely to accept the default channel"],"tags":["cli","argument-validation","update-cli"],"backgroundTag":"invalid-cli-arguments","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}