{"record":{"id":"3f4135cab64f93fd","repo":"jackwener/OpenCLI","slug":"homebrew-label-cannot-be-empty","errorCode":null,"errorMessage":"homebrew ${label} cannot be empty","messagePattern":"homebrew (.+?) cannot be empty","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/homebrew/utils.js","lineNumber":18,"sourceCode":"// Shared helpers for the Homebrew adapters.\n//\n// Hits the public, unauthenticated `formulae.brew.sh/api` JSON endpoints\n// (served as static files from GitHub Pages, regenerated daily). No auth.\n// Formula / cask tokens are lowercase ASCII + `-_.+@` per Homebrew's own\n// validation; they round-trip into `homebrew formula` / `homebrew cask`.\nimport { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\n\nexport const BREW_BASE = 'https://formulae.brew.sh/api';\nconst UA = 'opencli-homebrew-adapter (+https://github.com/jackwener/opencli)';\n\n// Homebrew formula / cask tokens — letters / digits / `_-.+@` (`gcc@13`,\n// `imagemagick@6`, `c++`, `0-ad`, `php-cs-fixer`).\nconst TOKEN = /^[A-Za-z0-9][A-Za-z0-9._+@-]*$/;\n\nexport function requireString(value, label) {\n    const s = String(value ?? '').trim();\n    if (!s) throw new ArgumentError(`homebrew ${label} cannot be empty`);\n    return s;\n}\n\nexport function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const n = typeof raw === 'number' ? raw : Number(raw);\n    if (!Number.isInteger(n) || n <= 0) {\n        throw new ArgumentError(`homebrew ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`homebrew ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requireToken(value, label) {\n    const s = String(value ?? '').trim();\n    if (!s) {","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/homebrew/utils.js#L1-L36","documentation":"requireString coerces its argument to a string, trims it, and throws ArgumentError('homebrew <label> cannot be empty') when the result is empty. It enforces that a required textual argument (e.g. a search query) was actually provided by the caller.","triggerScenarios":"Calling query('') or query(null)/query(undefined), or passing a CLI flag with no value (e.g. --query \"\" ) so the trimmed string is empty.","commonSituations":"Shell variable holding the query is unset/empty, quoting mistake yields an empty argument, or programmatic callers pass undefined fields.","solutions":["Pass a non-empty query string to the command","Check the shell variable/flag actually has a value before invoking","Validate arguments in the caller with an early check","Handle ArgumentError in the CLI layer with a usage message"],"exampleFix":"// before\nawait homebrewQuery(process.env.Q);\n// after\nconst q = (process.env.Q ?? '').trim();\nif (!q) throw new Error('--query is required');\nawait homebrewQuery(q);","handlingStrategy":"validation","validationCode":"const q = String(rawQuery ?? '').trim();\nif (!q) throw new Error(`homebrew query value is required (got: ${JSON.stringify(rawQuery)})`);","typeGuard":"function isNonEmptyString(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  await homebrewQuery(rawQuery);\n} catch (err) {\n  if (err instanceof ArgumentError && /cannot be empty/.test(err.message)) {\n    console.error('Usage: homebrew search <query>');\n    process.exitCode = 2;\n    return;\n  }\n  throw err;\n}","preventionTips":["Trim and check user input before passing it to the command","Guard against unset shell/CI variables with ${VAR:?} or defaults","Require positional args in your CLI wrapper before invoking","Catch ArgumentError to print friendly usage messages"],"tags":["validation","argument-error","input"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}