{"record":{"id":"e8a00df532746127","repo":"jackwener/OpenCLI","slug":"twitter-followers-user-cannot-be-empty","errorCode":null,"errorMessage":"twitter followers user cannot be empty","messagePattern":"twitter followers user cannot be empty","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/followers.js","lineNumber":128,"sourceCode":"        }\n\n        if (!targetUser) {\n            // Bridge wraps primitive page.evaluate returns as { session, data:<value> };\n            // unwrap so the href string is usable downstream.\n            const href = unwrapBrowserResult(await page.evaluate(`() => {\n                const link = document.querySelector('a[data-testid=\"AppTabBar_Profile_Link\"]');\n                return link ? link.getAttribute('href') : null;\n            }`));\n            if (!href || typeof href !== 'string') {\n                throw new AuthRequiredError('x.com', 'Could not find logged-in user profile link. Are you logged in?');\n            }\n            targetUser = normalizeScreenName(href);\n            if (!targetUser) {\n                throw new AuthRequiredError('x.com', 'Could not find logged-in user profile link. Are you logged in?');\n            }\n        }\n        if (!targetUser) {\n            throw new ArgumentError('twitter followers user cannot be empty', 'Example: opencli twitter followers @elonmusk --limit 100');\n        }\n\n        await page.installInterceptor('/Followers?');\n        const targetPath = `/${targetUser}/followers`;\n        await page.evaluate(`() => {\n            const targetPath = ${JSON.stringify(targetPath)};\n            window.history.pushState({}, '', targetPath);\n            window.dispatchEvent(new PopStateEvent('popstate', { state: {} }));\n        }`);\n        try {\n            await page.waitForCapture(CAPTURE_TIMEOUT_SECONDS);\n        }\n        catch {\n            throw new TimeoutError('twitter followers API capture', CAPTURE_TIMEOUT_SECONDS, 'No Followers response was observed after opening the followers list.');\n        }\n        const currentPath = unwrapBrowserResult(await page.evaluate('() => window.location.pathname'));\n        if (typeof currentPath !== 'string' || !currentPath.toLowerCase().endsWith('/followers')) {\n            throw new CommandExecutionError('SPA navigation to Twitter followers failed');","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/followers.js#L110-L146","documentation":"A final defensive check after both the explicit user argument and profile-link resolution paths: if targetUser is still falsy, the command refuses to navigate to '/undefined/followers' and throws ArgumentError with a usage example. In practice this is hard to reach because the earlier branches throw first — it protects against normalizeScreenName returning a falsy value that slipped through both prior guards (e.g. rawUser empty and href branch somehow skipped normalization).","triggerScenarios":"Reached only if kwargs.user is empty/whitespace AND the profile-link branch did not set targetUser (future code changes, or normalizeScreenName returning an empty string from an unexpected href without throwing at 4104/4105).","commonSituations":"Mostly defensive dead code today; can surface in forks or modified versions of the command where the earlier AuthRequiredError guards were removed or altered.","solutions":["Supply the user argument explicitly: opencli twitter followers @handle","Ensure normalizeTwitterScreenName in shared.js returns a non-empty handle for valid input","Verify you are calling the command with a non-empty, valid handle"],"exampleFix":"// before\nopencli twitter followers \"   \"\n// after\nopencli twitter followers @elonmusk --limit 100","handlingStrategy":"validation","validationCode":"const target = (raw ?? '').trim();\nif (!/^@?[A-Za-z0-9_]{1,15}$/.test(target)) throw new Error('supply a handle, e.g. @elonmusk');","typeGuard":"const hasTarget = (s) => typeof s === 'string' && s.trim().length > 0;","tryCatchPattern":"try {\n  await opencli.twitter.followers(user);\n} catch (err) {\n  if (err.message.includes('cannot be empty')) {\n    return opencli.twitter.followers(defaultHandle);\n  } else throw err;\n}","preventionTips":["Never pass empty or whitespace-only user values","Always pass an explicit handle in automated scripts","Sanitize kwargs before invoking the command func"],"tags":["validation","arguments","twitter"],"backgroundTag":"invalid-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}