{"record":{"id":"134ae986b5f79a9b","repo":"jackwener/OpenCLI","slug":"homebrew-label-is-required","errorCode":null,"errorMessage":"homebrew ${label} is required","messagePattern":"homebrew (.+?) is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/homebrew/utils.js","lineNumber":50,"sourceCode":"}\n\nexport function requireToken(value, label) {\n    const s = String(value ?? '').trim();\n    if (!s) {\n        throw new ArgumentError(`homebrew ${label} is required (e.g. \"wget\", \"gcc@13\", \"firefox\")`);\n    }\n    if (s.length > 100 || !TOKEN.test(s)) {\n        throw new ArgumentError(\n            `homebrew ${label} \"${value}\" is not a valid token`,\n            'Use letters / digits / \"_-.+@\", starting with a letter or digit (max 100 chars).',\n        );\n    }\n    return s;\n}\n\nexport function requireOneOf(value, allowed, label) {\n    const s = String(value ?? '').trim().toLowerCase();\n    if (!s) throw new ArgumentError(`homebrew ${label} is required`);\n    if (!allowed.includes(s)) {\n        throw new ArgumentError(\n            `homebrew ${label} \"${value}\" is not supported`,\n            `Allowed: ${allowed.join(', ')}.`,\n        );\n    }\n    return s;\n}\n\nexport async function brewFetch(url, label) {\n    let resp;\n    try {\n        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });\n    }\n    catch (err) {\n        throw new CommandExecutionError(\n            `${label} request failed: ${err?.message ?? err}`,\n            'Check that formulae.brew.sh is reachable from this network.',","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/homebrew/utils.js#L32-L68","documentation":"requireOneOf validates that an enum-like option (e.g. the `type` or `window` argument of homebrew commands) is a non-empty string belonging to a fixed allow-list. The library throws this ArgumentError when the value normalizes (trim + lowercase) to an empty string — meaning the argument was omitted, undefined/null, or whitespace-only. It fails fast at argument-validation time instead of sending a malformed request to the Homebrew API.","triggerScenarios":"Calling a homebrew command/function that routes through requireOneOf with the labeled argument missing: e.g. type(undefined), type(''), type('   '), type(null), or window(null). Any falsy-after-trim value produces this error.","commonSituations":"Scripting the CLI where a shell variable holding the type/window is unset or empty ($TYPE expands to nothing); programmatic use passing null/undefined because an upstream lookup failed; typo of the parameter name so the expected key never reaches the function.","solutions":["Pass one of the allowed values for the argument (e.g. type 'formula' or 'cask', a valid analytics window) instead of leaving it empty.","Check the calling script for unset/empty shell or config variables and add a default (e.g. TYPE=${TYPE:-formula}).","Read the error's label to see which argument is missing and consult the command's allowed-values list (the companion 'is not supported' error lists them)."],"exampleFix":"// before\nhomebrew popular --type \"$TYPE\" --window \"$WINDOW\"   # $TYPE unset -> ArgumentError\n// after\nhomebrew popular --type \"${TYPE:-formula}\" --window \"${WINDOW:-30d}\"","handlingStrategy":"validation","validationCode":"const HOMEBREW_TYPES = ['formula', 'cask'];\nfunction validateType(value) {\n  const s = String(value ?? '').trim().toLowerCase();\n  if (!s) throw new Error(`homebrew type is required (one of: ${HOMEBREW_TYPES.join(', ')})`);\n  return s;\n}","typeGuard":"function hasType(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  await run({ type });\n} catch (err) {\n  if (err instanceof ArgumentError && err.message.includes('is required')) {\n    type = 'formula'; // default and retry\n  } else throw err;\n}","preventionTips":["Always pass explicit enum values; never rely on unset shell variables.","Default type/window at the call site (${TYPE:-formula}).","Keep a constants list of allowed values next to the call and pick from it.","Lint scripts for interpolations that can expand to empty strings."],"tags":["argument-validation","missing-argument","cli"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}