{"record":{"id":"afbcbf5404c66d85","repo":"jackwener/OpenCLI","slug":"username-is-required-afbcbf","errorCode":null,"errorMessage":"username is required","messagePattern":"username is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/tiktok/utils.js","lineNumber":44,"sourceCode":"    if (!Number.isInteger(parsed) || parsed <= 0) {\n        throw new ArgumentError(\n            `${name} must be a positive integer`,\n            `Example: --${name} ${fallback}`,\n        );\n    }\n    if (parsed > max) {\n        throw new ArgumentError(\n            `${name} must be <= ${max}`,\n            `Example: --${name} ${max}`,\n        );\n    }\n    return parsed;\n}\n\nexport function normalizeUsername(value) {\n    const username = String(value ?? '').trim().replace(/^@+/, '');\n    if (!username) {\n        throw new ArgumentError(\n            'username is required',\n            'Example: opencli tiktok following <username>',\n        );\n    }\n    if (!/^[A-Za-z0-9._-]+$/.test(username)) {\n        throw new ArgumentError(\n            'username contains unsupported characters',\n            'Pass the TikTok handle without @, for example: dictogo',\n        );\n    }\n    return username;\n}\n\nexport const NOTIFICATION_TYPES = {\n    all: { code: 0, label: 'all' },\n    likes: { code: 3, label: 'likes' },\n    comments: { code: 7, label: 'comments' },\n    mentions: { code: 6, label: 'mentions' },","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/tiktok/utils.js#L26-L62","documentation":"normalizeUsername trims the input and strips leading '@' characters, then throws this ArgumentError if nothing remains. The CLI requires a concrete handle for user-scoped commands and will not proceed with a blank value.","triggerScenarios":"Omitting the <username> positional argument entirely; passing only '@' or '@@'; passing an empty string, null, or undefined; a shell variable expanding to empty (USER_NAME=\"\").","commonSituations":"Scripted invocations where the username variable is unset; copy-pasting a command template without filling the placeholder; piping arguments incorrectly so the positional arg is dropped.","solutions":["Pass the handle as a positional argument, e.g. opencli tiktok following dictogo.","Pass at least one usable character after '@' stripping ('@user' is fine, '@' alone is not).","Fix unset/empty shell variables with \"${USER_NAME:?username required}\".","In code, validate the value is a non-empty trimmed string before calling."],"exampleFix":"// before\nconst user = process.env.TT_USER; // undefined\nawait cli.tiktok.following(user); // throws\n// after\nconst user = process.env.TT_USER;\nif (!user || !String(user).replace(/^@+/, '').trim()) throw new Error('set TT_USER');\nawait cli.tiktok.following(user);","handlingStrategy":"validation","validationCode":"function requireHandle(v) {\n  const handle = String(v ?? '').trim().replace(/^@+/, '');\n  if (!handle) throw new Error('username is required: pass e.g. dictogo');\n  return handle;\n}\nrequireHandle(process.argv[2]);","typeGuard":"const hasUsername = (v) => typeof v === 'string' && v.trim().replace(/^@+/, '').length > 0;","tryCatchPattern":"try {\n  await cli.tiktok.following(username);\n} catch (e) {\n  if (e.message === 'username is required') {\n    console.error('Usage: opencli tiktok following <username>');\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Use \"${USER:?username required}\" in shell scripts to fail fast on unset vars","Always pass a positional handle argument; '@user' is fine, bare '@' is not","Validate CLI args with a regex before invoking in code","Read the command's usage line before scripting invocations"],"tags":["validation","argument-error","cli","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}