{"record":{"id":"70ece77911289cf3","repo":"jackwener/OpenCLI","slug":"twitter-download-username","errorCode":null,"errorMessage":"twitter download @${username}","messagePattern":"twitter download @(.+?)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/twitter/download.js","lineNumber":379,"sourceCode":"    });\n\n    const ubsUrl = buildUserByScreenNameUrl(userByScreenNameOperation, username);\n    const userLookup = requireFetchPayload(await page.evaluate(`async () => {\n      try {\n        const resp = await fetch(\"${ubsUrl}\", { headers: ${headers}, credentials: 'include' });\n        if (!resp.ok) return { ok: false, status: resp.status };\n        const payload = await resp.json();\n        return { ok: true, payload };\n      } catch (err) {\n        return { ok: false, error: err?.message ?? String(err) };\n      }\n    }`));\n    const normalizedUserLookup = normalizeTwitterGraphqlPayload(userLookup);\n    if (Array.isArray(normalizedUserLookup?.errors) && normalizedUserLookup.errors.length > 0) {\n        throw new CommandExecutionError(`Twitter UserByScreenName returned GraphQL errors: ${JSON.stringify(normalizedUserLookup.errors).slice(0, 200)}`);\n    }\n    const userId = normalizedUserLookup?.data?.user?.result?.rest_id;\n    if (!userId) throw new EmptyResultError(`twitter download @${username}`, `Could not resolve @${username}`);\n\n    const seen = new Set();\n    const all = [];\n    let cursor = null;\n    let hasMorePages = false;\n    for (let i = 0; i < MAX_PAGINATION_PAGES && all.length < limit; i++) {\n        const fetchCount = nextUserMediaFetchCount(limit, all.length);\n        if (fetchCount === 0) break;\n        const url = buildUserMediaUrl(userMediaOperation, userId, fetchCount, cursor);\n        const data = normalizeTwitterGraphqlPayload(requireFetchPayload(await page.evaluate(`async () => {\n        try {\n          const r = await fetch(\"${url}\", { headers: ${headers}, credentials: 'include' });\n          if (!r.ok) return { ok: false, status: r.status };\n          return { ok: true, payload: await r.json() };\n        } catch (err) {\n          return { ok: false, error: err?.message ?? String(err) };\n        }\n        }`)));","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/download.js#L361-L397","documentation":"If UserByScreenName returns no GraphQL errors but data.user.result.rest_id is still missing, the code throws EmptyResultError titled `twitter download @<username>` with detail 'Could not resolve @<username>'. This means Twitter's response was structurally valid but contained no user result payload.","triggerScenarios":"UserByScreenName returns an empty/partial data node: protected or deleted account edge cases, response shape changes after x.com updates, or responses where user.result lacks rest_id (e.g. some restricted states).","commonSituations":"x.com changed the GraphQL response shape so rest_id moved or was renamed; the account exists but its result is withheld in your region; caching/stale operation metadata producing a truncated response.","solutions":["Confirm the account is public and viewable at https://x.com/<username>","Update the CLI to match the current UserByScreenName response shape (rest_id path)","Retry later in case of transient server-side truncation"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"const userId = normalized?.data?.user?.result?.rest_id;\nif (!userId) {\n  console.warn('Could not resolve user; verify the account is public');\n}","typeGuard":"const hasResolvedUser = (payload) => typeof payload?.data?.user?.result?.rest_id === 'string';","tryCatchPattern":"try {\n  await cmd();\n} catch (err) {\n  if (err.name === 'EmptyResultError' && err.message.includes('Could not resolve')) {\n    // treat as 'user unresolvable' — verify account visibility\n  }\n}","preventionTips":["Verify the account is public and resolvable at x.com/<username>","Update the CLI when x.com changes the rest_id response path","Handle both EmptyResultError and GraphQL-error cases when scripting"],"tags":["graphql","empty-result","twitter"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}