{"record":{"id":"e9828874dfaa3a56","repo":"jackwener/OpenCLI","slug":"twitter-list-add-username-is-required","errorCode":null,"errorMessage":"twitter list-add username is required","messagePattern":"twitter list-add username is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/list-add-core.js","lineNumber":111,"sourceCode":"    return {\n        listId,\n        username,\n        userId: String(userId),\n        status: noop ? 'noop' : 'success',\n        message: noop\n            ? `@${username} is already a member of list ${listId}`\n            : `Added @${username} to list ${listId} (verified via ${verifiedBy})`,\n    };\n}\n\nexport async function listAddUser(page, kwargs) {\n        const listId = String(kwargs.listId || '').trim();\n        const username = String(kwargs.username || '').replace(/^@/, '').trim();\n        if (!listId || !/^\\d+$/.test(listId)) {\n            throw new ArgumentError(`Invalid listId: ${JSON.stringify(kwargs.listId)}. Expected numeric ID.`, 'Example: opencli twitter list-add 123456789 alice');\n        }\n        if (!username) {\n            throw new ArgumentError('twitter list-add username is required', 'Example: opencli twitter list-add 123456789 alice');\n        }\n        // Strategy.UI does not get a domain URL pre-nav from the framework.\n        // This page context is load-bearing for pre-target GraphQL calls below.\n        await page.goto('https://x.com');\n        await page.wait(3);\n        const cookies = await page.getCookies({ url: 'https://x.com' });\n        const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;\n        if (!ct0) throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');\n\n        const userByScreenNameQueryId = await resolveTwitterQueryId(page, 'UserByScreenName', USER_BY_SCREEN_NAME_QUERY_ID);\n\n        const headers = JSON.stringify({\n            'Authorization': `Bearer ${decodeURIComponent(TWITTER_BEARER_TOKEN)}`,\n            'X-Csrf-Token': ct0,\n            'X-Twitter-Auth-Type': 'OAuth2Session',\n            'X-Twitter-Active-User': 'yes',\n        });\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-add-core.js#L93-L129","documentation":"An ArgumentError from listAddUser thrown when kwargs.username is empty after stripping a leading '@' and trimming. The command needs the screen name of the user to add to the list, and raises with an example usage when it is absent.","triggerScenarios":"listAddUser called with username undefined/null, an empty string, or a value consisting solely of '@'.","commonSituations":"Forgetting the username argument on the CLI; a scripting variable left empty (e.g. from an unfilled CSV row or failed lookup); passing only '@' after the framework stripped the handle.","solutions":["Pass the target screen name: opencli twitter list-add 123456789 alice (leading '@' is optional and stripped).","Validate that the username variable is non-empty in your script before invoking.","If usernames come from a file/pipeline, filter out blank rows first.","Confirm you are passing the username as its own argument and not being swallowed by a flag."],"exampleFix":"// before\nconst users = ['alice', ''].filter(u => u.startsWith('@'));\nawait listAddUser(page, { listId, username: users[1] }); // '@'-less '' slips through\n// after\nconst users = ['alice', ''].map(u => u.replace(/^@/, '')).filter(Boolean);\nfor (const u of users) await listAddUser(page, { listId, username: u });","handlingStrategy":"validation","validationCode":"function toUsername(input) {\n  const u = String(input ?? '').replace(/^@/, '').trim();\n  if (!u) throw new Error('username is required');\n  return u;\n}\nconst usernames = rawList.map(toUsername).filter(Boolean);","typeGuard":"function isValidUsername(v) {\n  return typeof v === 'string' && v.replace(/^@/, '').trim().length > 0;\n}","tryCatchPattern":"try {\n  await listAddUser(page, { listId, username });\n} catch (e) {\n  if (e instanceof ArgumentError && /username is required/.test(e.message)) {\n    console.error('Provide a screen name: opencli twitter list-add 123456789 alice');\n  }\n  throw e;\n}","preventionTips":["Always pass the screen name as its own CLI argument.","Strip '@' and trim usernames sourced from files or APIs before calling.","Filter blank entries out of batch username lists.","Validate inputs in a loop before starting any mutations."],"tags":["twitter","argument-validation","cli","input-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}