{"record":{"id":"3167d9f9fb724734","repo":"can1357/oh-my-pi","slug":"invalid-selection-choice","errorCode":null,"errorMessage":"Invalid selection: ${choice}","messagePattern":"Invalid selection: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/auth-broker-cli.ts","lineNumber":365,"sourceCode":"\t});\n\treturn promise;\n}\n\nasync function pickProviderInteractively(providers: readonly OAuthProviderInfo[]): Promise<string> {\n\tif (providers.length === 0) {\n\t\tthrow new Error(\"No OAuth providers registered\");\n\t}\n\tconst rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\ttry {\n\t\tprocess.stdout.write(\"Select a provider:\\n\\n\");\n\t\tfor (let i = 0; i < providers.length; i++) {\n\t\t\tprocess.stdout.write(`  ${i + 1}. ${providers[i].name}\\n`);\n\t\t}\n\t\tprocess.stdout.write(\"\\n\");\n\t\tconst choice = await promptLine(rl, `Enter number (1-${providers.length}): `);\n\t\tconst index = Number.parseInt(choice, 10) - 1;\n\t\tif (Number.isNaN(index) || index < 0 || index >= providers.length) {\n\t\t\tthrow new Error(`Invalid selection: ${choice}`);\n\t\t}\n\t\treturn providers[index].id;\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function runRemoteLogin(provider: string, via: string, dryRun: boolean): Promise<void> {\n\tconst port = CALLBACK_PORTS[provider];\n\tif (port === undefined) {\n\t\tthrow new Error(\n\t\t\t`No known OAuth callback port for '${provider}'. Use device-code flow on the broker host directly.`,\n\t\t);\n\t}\n\tconst sshArgs = [\n\t\t\"-L\",\n\t\t`${port}:127.0.0.1:${port}`,\n\t\t\"-o\",","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/auth-broker-cli.ts#L347-L383","documentation":"After printing the numbered provider menu, `pickProviderInteractively` parses the user's line with `parseInt` and bounds-checks it against `1..providers.length`. Anything that is not a valid in-range integer throws this error instead of indexing out of bounds.","triggerScenarios":"Answering the `Enter number (1-N)` prompt with an empty line, non-numeric text ('yes', 'q'), or a number outside the menu range; EOF/piped stdin producing an unparseable line.","commonSituations":"Interactive login with fat-fingered input; scripted runs piping arbitrary text into the prompt; pressing Enter expecting a default selection.","solutions":["Re-run the login and enter a number between 1 and the number of listed providers.","Use `--provider=<id>` to bypass the interactive menu.","When scripting, pipe exactly one valid number (e.g. `echo 2 | omp auth-broker login`)."],"exampleFix":"// before\necho \"\" | omp auth-broker login        // Invalid selection: \n// after\nomp auth-broker login --provider=github","handlingStrategy":"validation","validationCode":"// feed only a valid menu index when scripting\nconst choice = 2;\nif (!Number.isInteger(choice) || choice < 1 || choice > providerCount) {\n  throw new Error(`choose 1..${providerCount}`);\n}\nawait prompt.write(String(choice) + \"\\n\");","typeGuard":null,"tryCatchPattern":"try {\n  await runLogin(flags);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Invalid selection:\")) {\n    console.error(\"Enter a number from the printed menu, or use --provider=<id>.\");\n  } else throw err;\n}","preventionTips":["Use `--provider=<id>` to bypass interactive menus entirely.","Don't pipe arbitrary text into interactive prompts; send exactly one valid number.","Answer with the number shown, not the provider name."],"tags":["cli","input-validation","interactive"],"backgroundTag":"invalid-user-input","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}