{"record":{"id":"a6c5cbc2bbd23ae8","repo":"jackwener/OpenCLI","slug":"youtube-search-label-must-be-one-of-object-k","errorCode":null,"errorMessage":"youtube search ${label} must be one of: ${Object.keys(choices).join(', ')}","messagePattern":"youtube search (.+?) must be one of: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/youtube/search.js","lineNumber":42,"sourceCode":"};\nconst UPLOAD_FILTERS = {\n    hour: 'EgIIAQ%3D%3D',\n    today: 'EgIIAg%3D%3D',\n    week: 'EgIIAw%3D%3D',\n    month: 'EgIIBA%3D%3D',\n    year: 'EgIIBQ%3D%3D',\n};\nconst SORT_FILTERS = {\n    relevance: '',\n    date: 'CAI%3D',\n    views: 'CAM%3D',\n    rating: 'CAE%3D',\n};\n\nfunction normalizeChoice(value, choices, label) {\n    const normalized = String(value || '').trim();\n    if (normalized && !Object.hasOwn(choices, normalized)) {\n        throw new ArgumentError(`youtube search ${label} must be one of: ${Object.keys(choices).join(', ')}`);\n    }\n    return normalized;\n}\n\nfunction normalizeLimit(value) {\n    const limit = Number(value ?? DEFAULT_LIMIT);\n    if (!Number.isInteger(limit) || limit <= 0) {\n        throw new ArgumentError('youtube search limit must be a positive integer');\n    }\n    if (limit > MAX_LIMIT) {\n        throw new ArgumentError(`youtube search limit must be <= ${MAX_LIMIT}`);\n    }\n    return limit;\n}\n\ncli({\n    site: 'youtube',\n    name: 'search',","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/search.js#L24-L60","documentation":"ArgumentError from normalizeChoice validating the --type, --upload, or --sort options for youtube search. The value must be an exact key of the corresponding filter map (type: shorts|video|channel|playlist; upload: hour|today|week|month|year; sort: relevance|date|views|rating). Empty/omitted values are allowed, but any non-empty unknown string throws.","triggerScenarios":"`youtube search <query> --type films` (not in TYPE_FILTERS), `--upload yesterday` (valid: hour,today,week,month,year), `--sort newest` (valid: relevance,date,views,rating), including case or whitespace variants like `--type Video`.","commonSituations":"Guessing filter names instead of reading --help, copying values from YouTube's UI (which differ from the CLI's canonical keys), typos and pluralization, or scripts passing user input unvalidated.","solutions":["Use exactly: type = shorts|video|channel|playlist; upload = hour|today|week|month|year; sort = relevance|date|views|rating","Run `opencli youtube search --help` to see accepted values","Trim/lowercase and map values before passing user-controlled input","Omit the flag entirely instead of passing a guessed value"],"exampleFix":"// before\nopencli youtube search \"lofi\" --type films --sort newest\n// after\nopencli youtube search \"lofi\" --type video --sort date","handlingStrategy":"validation","validationCode":"const TYPE_FILTERS = ['shorts','video','channel','playlist'];\nconst UPLOAD_FILTERS = ['hour','today','week','month','year'];\nconst SORT_FILTERS = ['relevance','date','views','rating'];\nfunction validateSearchArgs({ type = '', upload = '', sort = '' } = {}) {\n  for (const [label, v, allowed] of [['type',type,TYPE_FILTERS],['upload',upload,UPLOAD_FILTERS],['sort',sort,SORT_FILTERS]]) {\n    const n = String(v || '').trim();\n    if (n && !allowed.includes(n)) throw new Error(`youtube search ${label} must be one of: ${allowed.join(', ')}`);\n  }\n}","typeGuard":"const isSearchFilter = (v, allowed) => typeof v === 'string' && (v.trim() === '' || allowed.includes(v.trim()));","tryCatchPattern":"try {\n  await run('youtube search', [query, '--type', type]);\n} catch (e) {\n  if (/must be one of:/.test(e.message)) {\n    console.error('Bad filter value:', e.message);\n  } else throw e;\n}","preventionTips":["Only pass values from the documented lists (see --help)","Normalize user input with trim()/toLowerCase() before mapping to allowed keys","Maintain a whitelist map from your app's terms to CLI filter keys","Omit the flag rather than guessing a value"],"tags":["youtube","search","argument-validation","cli"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}