{"record":{"id":"3fb3dcaf05b0c324","repo":"jackwener/OpenCLI","slug":"rubygems-gem-name-is-required-e-g-rails-side","errorCode":null,"errorMessage":"rubygems gem name is required (e.g. \"rails\", \"sidekiq\")","messagePattern":"rubygems gem name is required \\(e\\.g\\. \"rails\", \"sidekiq\"\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/rubygems/utils.js","lineNumber":36,"sourceCode":"    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(`rubygems ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`rubygems ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requireGemName(value) {\n    const s = String(value ?? '').trim();\n    if (!s) {\n        throw new ArgumentError('rubygems gem name is required (e.g. \"rails\", \"sidekiq\")');\n    }\n    if (s.length > 100 || !GEM_NAME.test(s)) {\n        throw new ArgumentError(\n            `rubygems gem \"${value}\" is not a valid gem name`,\n            'Use letters / digits / \"._-\", starting with a letter or digit (max 100 chars).',\n        );\n    }\n    return s;\n}\n\nexport async function gemsFetch(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}`,","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/rubygems/utils.js#L18-L54","documentation":"requireGemName in clis/rubygems/utils.js throws ArgumentError('rubygems gem name is required (e.g. \"rails\", \"sidekiq\")') when the gem-name argument is null, undefined, or an empty/whitespace string. Gem-based commands (info, versions, etc.) require an explicit gem name, so the library fails fast with usage hints.","triggerScenarios":"Calling a gem command without the name argument: gemInfo({}) / gemInfo({ name: '' }) / gemInfo({ name: '   ' }) — requireGemName receives an empty value.","commonSituations":"Omitting the positional gem argument on the CLI (`opencli rubygems info`); a script variable holding the gem name being unset; piping an empty value into the command.","solutions":["Pass the gem name explicitly: `opencli rubygems info rails`.","Verify the variable feeding the argument is populated (`echo \"$GEM\"`).","Add a usage check in your script before invoking: `[ -n \"$GEM\" ] || { echo 'usage: ... <gem>'; exit 1; }`."],"exampleFix":"// before\nawait info({ name: '' }); // throws\n\n// after\nconst name = process.argv[2];\nif (!name) {\n  console.error('usage: rubygems info <gem>');\n  process.exit(1);\n}\nawait info({ name });","handlingStrategy":"validation","validationCode":"function requireNameArg(name) {\n  const s = String(name ?? '').trim();\n  if (!s) throw new Error('gem name is required, e.g. rails or sidekiq');\n  return s;\n}","typeGuard":"function isNonEmptyString(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  await info({ name: args.name });\n} catch (e) {\n  if (e instanceof ArgumentError && /gem name is required/.test(e.message)) {\n    console.error('usage: rubygems info <gem>');\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Make the gem name a required positional argument with a usage check.","Guard unset environment variables in shell scripts before invoking.","Trim inputs; whitespace-only names fail the same check."],"tags":["validation","argument-error","cli-input","rubygems"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}