{"record":{"id":"27f7275f3c56b631","repo":"jackwener/OpenCLI","slug":"dockerhub-label-cannot-be-empty","errorCode":null,"errorMessage":"dockerhub ${label} cannot be empty","messagePattern":"dockerhub (.+?) cannot be empty","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/dockerhub/utils.js","lineNumber":18,"sourceCode":"// Shared helpers for the Docker Hub adapters.\n//\n// Hits the public, unauthenticated `hub.docker.com/v2` REST endpoints. Anonymous\n// pulls are throttled but search / metadata reads are friendly enough for\n// ad-hoc CLI use. Image names follow `[<owner>/]<name>` with `library` as the\n// implicit owner for Docker official images.\nimport { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\n\nexport const HUB_BASE = 'https://hub.docker.com/v2';\nconst UA = 'opencli-dockerhub-adapter (+https://github.com/jackwener/opencli)';\n\n// Docker Hub repository slugs are 2-255 chars, lowercase alphanumerics + `_.-`,\n// optionally prefixed with a Docker Hub user/org of the same charset.\nconst SLUG = /^[a-z0-9][a-z0-9._-]*$/;\n\nexport function requireString(value, label) {\n    const s = String(value ?? '').trim();\n    if (!s) throw new ArgumentError(`dockerhub ${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(`dockerhub ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`dockerhub ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\n/**\n * Split an image identifier into `{owner, name}`. Bare names use the implicit\n * `library` owner that Docker Hub uses for official images (`nginx` →","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dockerhub/utils.js#L1-L36","documentation":"requireString validates that a labeled CLI argument is a non-empty string after trimming. This ArgumentError is thrown when the value is missing, null, undefined, or whitespace-only. It guards API calls against empty query parameters.","triggerScenarios":"Calling dockerhub search (or any command using requireString(args.query,'query')) without --query; passing --query '' or --query ' '; an unset shell variable expanding to nothing.","commonSituations":"Scripts where the search term variable is empty; forgetting a required flag in CI pipelines; copy-pasting a command with a placeholder left in quotes.","solutions":["Provide the required --query value","Check that the shell variable feeding the flag is non-empty","Trim/validate user input before passing it to the CLI"],"exampleFix":"// before\ndockerhub search --query \"$TERM\"   # TERM unset -> empty\n// after\n: \"${TERM:?TERM must be set}\" && dockerhub search --query \"$TERM\"","handlingStrategy":"validation","validationCode":"const query = (args.query ?? '').trim(); if (!query) throw new Error('--query must be a non-empty string');","typeGuard":"function isNonEmptyString(v) { return typeof v === 'string' && v.trim() !== ''; }","tryCatchPattern":"try { await search(args); } catch (e) { if (e instanceof ArgumentError && e.message.includes('cannot be empty')) { console.error(`Missing required --${e.message.replace('dockerhub ','').replace(' cannot be empty','')}`); process.exitCode = 2; } else throw e; }","preventionTips":["Check required flags before invoking the CLI","Guard shell variables with : \"${VAR:?}\"","Trim user input before passing it through"],"tags":["argument-validation","cli","dockerhub"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}