{"record":{"id":"866038ba9a6e3708","repo":"jackwener/OpenCLI","slug":"label-is-required-866038","errorCode":null,"errorMessage":"${label} is required","messagePattern":"(.+?) is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":14,"sourceCode":"import { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError, AuthRequiredError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\nimport {\n  canonicalizeLinkedInThreadUrl,\n  normalizeWhitespace,\n  requireLinkedInCookie,\n  unwrapEvaluateResult,\n} from './shared.js';\n\nconst LINKEDIN_DOMAIN = 'www.linkedin.com';\n\nfunction requireStringArg(args, key, label = key) {\n  const value = normalizeWhitespace(args[key]);\n  if (!value) throw new ArgumentError(`${label} is required`);\n  return value;\n}\n\nfunction requireLinkedInThreadUrl(value, label) {\n  const url = canonicalizeLinkedInThreadUrl(value);\n  if (!url) throw new ArgumentError(`${label} must be an exact https://www.linkedin.com/messaging/thread/<id>/ URL`);\n  return url;\n}\n\nfunction parseMaxScrolls(value) {\n  if (value === undefined || value === null || value === '') return 30;\n  const scrolls = Number(value);\n  if (!Number.isInteger(scrolls) || scrolls < 0 || scrolls > 80) {\n    throw new ArgumentError('--max-scrolls must be an integer between 0 and 80');\n  }\n  return scrolls;\n}\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L1-L32","documentation":"thread-snapshot.js defines its own local requireStringArg: it normalizes whitespace on args[key] and throws ArgumentError with `${label} is required` when empty. It enforces required arguments like the thread URL before any scraping begins.","triggerScenarios":"Invoking the thread-snapshot command without the thread URL argument, or with an empty/whitespace-only value, e.g. `linkedin thread-snapshot --thread-url \"\"`.","commonSituations":"Scripts where the thread URL variable is unset, copy-paste omitted the flag value, or a wrapper passed an empty string after trimming.","solutions":["Provide the required argument, e.g. `--thread-url \"https://www.linkedin.com/messaging/thread/<id>/\"`.","Check the error's label to see which key was missing.","Validate the source (env var, config) is non-empty before invoking the CLI.","Pass a real thread ID string, not an empty placeholder."],"exampleFix":"// before\nnode cli.js thread-snapshot --thread-url \"$THREAD_URL\"   # THREAD_URL unset -> empty\n// after\n: \"${THREAD_URL:?THREAD_URL is required}\"\nnode cli.js thread-snapshot --thread-url \"$THREAD_URL\"","handlingStrategy":"validation","validationCode":"function assertThreadUrlArg(args) {\n  const v = typeof args?.['thread-url'] === 'string' ? args['thread-url'].trim() : '';\n  if (!v) throw new Error('--thread-url is required');\n  return v;\n}","typeGuard":"function hasThreadUrlArg(args) {\n  return typeof args?.['thread-url'] === 'string' && args['thread-url'].trim().length > 0;\n}","tryCatchPattern":"try {\n  await threadSnapshot(args);\n} catch (e) {\n  if (e instanceof ArgumentError && / is required$/.test(e.message)) {\n    console.error(`Missing required argument: ${e.message.replace(' is required', '')} (pass --thread-url ...)`);\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Always pass --thread-url when invoking thread-snapshot.","Fail fast on empty env vars with :? expansion in shell wrappers.","Trim inputs; whitespace-only values are rejected.","Document required flags in wrapper scripts."],"tags":["argument-validation","missing-argument","cli","linkedin"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}