{"record":{"id":"684ff57ff1ecb092","repo":"jackwener/OpenCLI","slug":"invalid-listid-json-stringify-kwargs-listid","errorCode":null,"errorMessage":"Invalid listId: ${JSON.stringify(kwargs.listId)}. Expected numeric ID.","messagePattern":"Invalid listId: (.+?)\\. Expected numeric ID\\.","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/list-add-core.js","lineNumber":108,"sourceCode":"        );\n    }\n    const verifiedBy = `member_count ${memberCountBefore} → ${memberCountAfter}`;\n    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',","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-add-core.js#L90-L126","documentation":"An ArgumentError from listAddUser in `clis/twitter/list-add-core.js` thrown when kwargs.listId is missing, empty, or not purely numeric after trimming. The CLI requires the raw numeric X list ID (e.g. 123456789), not a slug like 'my-list' or a full x.com/i/lists/... URL, and includes an example usage in the error.","triggerScenarios":"listAddUser called with listId undefined/null, an empty string, a list slug ('my-cool-list'), a URL ('https://x.com/i/lists/123456789'), or a value with non-digit characters.","commonSituations":"Passing the list name from the X UI instead of its numeric ID; pasting the whole list URL; forgetting the listId argument so undefined is passed; scripting with a variable that was never set.","solutions":["Extract the numeric ID from the list URL (the digits in x.com/i/lists/<id>) and pass only that.","Strip any surrounding URL/slug before calling — String(listId).trim() must match /^\\d+$/.","Ensure the listId variable is actually populated before invoking listAddUser.","Use the documented form: opencli twitter list-add 123456789 alice"],"exampleFix":"// before\nawait listAddUser(page, { listId: 'https://x.com/i/lists/123456789', username: 'alice' });\n// after\nconst listId = url.match(/\\/lists\\/(\\d+)/)?.[1];\nawait listAddUser(page, { listId, username: 'alice' });","handlingStrategy":"validation","validationCode":"function toNumericListId(input) {\n  const s = String(input ?? '').trim();\n  const fromUrl = s.match(/\\/lists\\/(\\d+)/)?.[1];\n  const id = fromUrl ?? s;\n  if (!/^\\d+$/.test(id)) throw new Error(`listId must be numeric, got: ${input}`);\n  return id;\n}\nconst listId = toNumericListId(rawListId);","typeGuard":"function isValidListId(v) {\n  return typeof v !== 'undefined' && v !== null && /^\\d+$/.test(String(v).trim());\n}","tryCatchPattern":"try {\n  await listAddUser(page, { listId, username });\n} catch (e) {\n  if (e instanceof ArgumentError && /Invalid listId/.test(e.message)) {\n    // message includes the expected format and an example invocation\n    console.error('Pass the numeric list ID, e.g. opencli twitter list-add 123456789 alice');\n  }\n  throw e;\n}","preventionTips":["Copy the digits from x.com/i/lists/<id>, not the slug or full URL.","Normalize URLs to IDs with /\\/lists\\/(\\d+)/ before calling.","Assert listId is truthy and numeric in scripts before invoking.","Never pass the human-readable list name as listId."],"tags":["twitter","argument-validation","cli","input-validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}