{"record":{"id":"006449318832b19d","repo":"jackwener/OpenCLI","slug":"twitter-profile","errorCode":null,"errorMessage":"twitter profile","messagePattern":"twitter profile","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/profile.js","lineNumber":181,"sourceCode":"        if (!result) return {ok: false, notFound: true, error: 'User @' + screenName + ' not found'};\n        return {ok: true, result};\n      }\n    `));\n        if (!isPlainObject(rawResult)) {\n            throw new CommandExecutionError('Twitter profile response payload is malformed');\n        }\n        if (!rawResult.ok) {\n            // For HTTP errors, use fork's rich code mapping (429/401/403/404/5xx differentiation\n            // from describeTwitterApiError); fall back to the plain message for non-HTTP failures\n            // (fetch threw, JSON parse failed, payload malformed).\n            const message = typeof rawResult.httpStatus === 'number'\n                ? describeTwitterApiError('UserByScreenName', rawResult.httpStatus, rawResult.hint)\n                : rawResult.error + (rawResult.hint ? ` (${rawResult.hint})` : '');\n            if (rawResult.auth) {\n                throw new AuthRequiredError('x.com', message);\n            }\n            if (rawResult.notFound) {\n                throw new EmptyResultError('twitter profile', message);\n            }\n            throw new CommandExecutionError(message);\n        }\n        return mapTwitterProfileResult(rawResult.result, username);\n    }\n});\n\nexport const __test__ = { mapTwitterProfileResult };\n","sourceCodeStart":163,"sourceCodeEnd":190,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/profile.js#L163-L190","documentation":"EmptyResultError('twitter profile') thrown when rawResult.notFound is set — the UserByScreenName response indicated the screen name does not resolve to a user (Twitter returns success with data.user.result absent). It is the typed 'no such entity' outcome, distinct from auth or transport failures.","triggerScenarios":"Querying @username that does not exist, was renamed, or is suspended/protected so the GraphQL response has no user.result, making the in-page script return {ok:false, notFound:true}.","commonSituations":"Typo in the handle; account deleted or renamed since data was collected; querying suspended/banned accounts; region or age-gated profiles; scraping stale handle lists.","solutions":["Verify the screen name spelling and that the account still exists by opening https://x.com/<username>","Treat EmptyResultError as 'user not found' in your pipeline and skip the record instead of retrying","Re-fetch the current handle from your source of truth if the account may have been renamed","Check whether the profile is suspended/private; those cannot be fetched without following/access"],"exampleFix":"// before\nconst profile = await cli.run('twitter profile', { username: handle });\n// after\ntry {\n  const profile = await cli.run('twitter profile', { username: handle });\n} catch (e) {\n  if (e instanceof EmptyResultError) return skip(handle); // user does not exist\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isEmptyResultError(e) {\n  return e instanceof EmptyResultError || e.name === 'EmptyResultError';\n}","tryCatchPattern":"try {\n  return await cli.run('twitter profile', { username });\n} catch (e) {\n  if (e instanceof EmptyResultError) return null; // user does not exist\n  throw e;\n}","preventionTips":["Normalize handles (strip @, trim whitespace, lowercase check) before lookup","Maintain a not-found cache to avoid re-querying dead handles","Periodically re-validate handle lists against renames/suspensions","Treat not-found as data, not as a retryable fault"],"tags":["not-found","user-lookup","twitter-api"],"backgroundTag":"entity-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}