{"record":{"id":"abe194ad15a4ad72","repo":"jackwener/OpenCLI","slug":"shot-is-required-numeric-id-or-dribbble-com-shots","errorCode":null,"errorMessage":"shot is required (numeric id or dribbble.com/shots URL)","messagePattern":"shot is required \\(numeric id or dribbble\\.com/shots URL\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/dribbble/utils.js","lineNumber":50,"sourceCode":"\nexport function optionalQuery(value, label = 'query') {\n    const query = String(value ?? '').trim();\n    if (query.length > 100) throw new ArgumentError(`${label} must be <= 100 characters`);\n    return query;\n}\n\nexport function requireDesigner(value) {\n    const designer = String(value ?? '').trim();\n    if (!designer) throw new ArgumentError('designer is required (for example: halolab)');\n    if (!/^[A-Za-z0-9_-]{1,100}$/.test(designer)) {\n        throw new ArgumentError('designer must be a Dribbble username or profile slug');\n    }\n    return designer;\n}\n\nexport function requireShotTarget(value) {\n    const target = String(value ?? '').trim();\n    if (!target) throw new ArgumentError('shot is required (numeric id or dribbble.com/shots URL)');\n    if (/^\\d+$/.test(target)) return target;\n\n    let url;\n    try {\n        url = new URL(target);\n    } catch {\n        throw new ArgumentError('shot must be a numeric id or dribbble.com/shots URL');\n    }\n    if (!/(^|\\.)dribbble\\.com$/i.test(url.hostname)) {\n        throw new ArgumentError('shot URL must use dribbble.com');\n    }\n    const match = url.pathname.match(/^\\/shots\\/(\\d+)(?:-|\\/|$)/);\n    if (!match) throw new ArgumentError('shot URL must match dribbble.com/shots/<id>');\n    return match[1];\n}\n\nexport function requireRows(payload, command) {\n    if (!payload || typeof payload !== 'object') {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dribbble/utils.js#L32-L68","documentation":"requireShotTarget validates the shot argument, accepting either a numeric shot id or a dribbble.com/shots URL. This ArgumentError is thrown when the value is missing or blank after String coercion and trim. Without a shot target no shot lookup can be built.","triggerScenarios":"Calling a shot command (via `shotId` -> requireShotTarget) with undefined/null, '', a whitespace-only string, or a value coercing to an empty string.","commonSituations":"Omitting the shot id on the CLI, an empty cell in a spreadsheet/batch script feeding shot ids, or a variable left undefined because a previous extraction step failed silently.","solutions":["Supply a numeric shot id (e.g. '1234567') or a full dribbble.com/shots URL.","Verify the input source (CLI flag, env var, loop variable) actually contains the id.","Guard batch scripts: skip or log rows whose shot field is empty instead of passing '' through."],"exampleFix":"// before\nconst rows = items.map(i => cli.shot({ shot: i.shotId })); // some shotId are ''\n\n// after\nconst rows = items.filter(i => i.shotId && String(i.shotId).trim()).map(i => cli.shot({ shot: i.shotId }));","handlingStrategy":"validation","validationCode":"const shot = value == null ? '' : String(value).trim();\nif (!shot) throw new Error('shot is required: numeric id or dribbble.com/shots URL');","typeGuard":"function hasShotTarget(v) {\n  return v != null && String(v).trim().length > 0;\n}","tryCatchPattern":"try {\n  const result = command({ shot });\n} catch (e) {\n  if (e instanceof ArgumentError && /shot is required/.test(e.message)) {\n    console.error('No shot id/URL provided; pass 1234567 or https://dribbble.com/shots/1234567');\n    return;\n  }\n  throw e;\n}","preventionTips":["Validate shot fields in batch inputs before the loop and skip/log empty entries.","Use required-argument flags in your CLI parser so omission fails before the library call.","Guard against silent upstream failures leaving the shot variable undefined."],"tags":["argument-validation","missing-argument","input-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}