{"record":{"id":"aabfb38effc2f44f","repo":"jackwener/OpenCLI","slug":"pick-label-cannot-be-empty","errorCode":null,"errorMessage":"--pick label cannot be empty","messagePattern":"--pick label cannot be empty","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/codex/send.js","lineNumber":11,"sourceCode":"import { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError, CommandExecutionError, selectorError } from '@jackwener/opencli/errors';\nimport { unwrapEvaluateResult } from './_actions.js';\nimport { conversationSelectionArgs, openCodexConversation } from './sidebar.js';\n\nconst PICKER_ITEM_SELECTOR = '[data-list-navigation-item=\"true\"]';\n\nexport function findUniquePickerOption(options, rawLabel) {\n    const wanted = String(rawLabel ?? '').replace(/\\s+/g, ' ').trim().toLowerCase();\n    if (!wanted) {\n        throw new ArgumentError('--pick label cannot be empty');\n    }\n    const normalized = options.map((option, index) => ({\n        index,\n        title: String(option.title ?? ''),\n        normalizedTitle: String(option.title ?? '').replace(/\\s+/g, ' ').trim().toLowerCase(),\n        normalizedText: String(option.text ?? option.title ?? '').replace(/\\s+/g, ' ').trim().toLowerCase(),\n    }));\n    const exact = normalized.filter(item => item.normalizedTitle === wanted);\n    if (exact.length === 1) {\n        return exact[0];\n    }\n    if (exact.length > 1) {\n        throw new CommandExecutionError(`Picker option \"${rawLabel}\" is ambiguous.`, `Matches: ${exact.map(item => item.title).join(', ')}`);\n    }\n    const partial = normalized.filter(item => item.normalizedText.includes(wanted));\n    if (partial.length === 1) {\n        return partial[0];\n    }","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/codex/send.js#L1-L29","documentation":"findUniquePickerOption normalizes the --pick label (collapse whitespace, trim, lowercase) and throws ArgumentError immediately when the normalized label is empty, since there is nothing meaningful to match picker options against.","triggerScenarios":"Calling sendCommand (which calls findUniquePickerOption) with rawLabel being null/undefined, an empty string, or a string of only whitespace such as '--pick \" \"'.","commonSituations":"Passing an unset shell variable as --pick \"$PICK\"; quoting mistakes that drop the value; programmatically passing kwargs.pick = '' ; whitespace-only label copied from UI text.","solutions":["Provide a non-empty --pick label matching (a part of) the picker option title.","Validate/trim the pick value before calling and fall back to no --pick if empty.","Check shell quoting and variable expansion so the label isn't dropped."],"exampleFix":"// before\nconst pick = process.env.PICK; // undefined\ncodexSend({ pick }); // ArgumentError: --pick label cannot be empty\n\n// after\nconst pick = (process.env.PICK || '').trim();\ncodexSend(pick ? { pick } : {});","handlingStrategy":"validation","validationCode":"const pick = String(kwargs.pick ?? '').trim();\nif (kwargs.pick != null && !pick) {\n  throw new Error('--pick given but empty; omit it or provide a label');\n}","typeGuard":"function isValidPickLabel(v) {\n  return v == null || (typeof v === 'string' && v.trim().length > 0);\n}","tryCatchPattern":"try {\n  await codexSend({ text, pick });\n} catch (e) {\n  if (e instanceof ArgumentError && /--pick/.test(e.message)) {\n    console.error('Fix or drop the --pick flag.');\n    process.exitCode = 2;\n    return;\n  }\n  throw e;\n}","preventionTips":["Omit --pick entirely when you have no label.","Trim and check pick labels in wrapper scripts before passing.","Guard shell interpolations: only add --pick when the variable is non-empty."],"tags":["argument-validation","input-validation","codex","picker"],"backgroundTag":"missing-or-empty-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}