{"record":{"id":"4ded77777e8457c4","repo":"jackwener/OpenCLI","slug":"twitter-profile-response-for-screenname-is-mal","errorCode":null,"errorMessage":"Twitter profile response for @${screenName} is malformed","messagePattern":"Twitter profile response for @(.+?) is malformed","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/profile.js","lineNumber":43,"sourceCode":"function isPlainObject(value) {\n    return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction stringField(value) {\n    return typeof value === 'string' ? value : '';\n}\n\nfunction countField(...values) {\n    for (const value of values) {\n        if (typeof value === 'number' && Number.isFinite(value))\n            return value;\n    }\n    return 0;\n}\n\nexport function mapTwitterProfileResult(result, screenName) {\n    if (!isPlainObject(result)) {\n        throw new CommandExecutionError(`Twitter profile response for @${screenName} is malformed`);\n    }\n    const hasLegacy = isPlainObject(result.legacy);\n    const hasCore = isPlainObject(result.core);\n    if (!hasLegacy && !hasCore) {\n        throw new CommandExecutionError(`Twitter profile response for @${screenName} is missing profile fields`);\n    }\n    const legacy = hasLegacy ? result.legacy : {};\n    const core = hasCore ? result.core : {};\n    if (!stringField(core.screen_name) && !stringField(legacy.screen_name) && !stringField(core.name) && !stringField(legacy.name) && !stringField(core.created_at) && !stringField(legacy.created_at)) {\n        throw new CommandExecutionError(`Twitter profile response for @${screenName} is missing profile identity fields`);\n    }\n    const location = isPlainObject(result.location) ? result.location : {};\n    const expandedUrl = stringField(result.website?.url) || stringField(legacy.entities?.url?.urls?.[0]?.expanded_url);\n    return [{\n        screen_name: stringField(core.screen_name) || stringField(legacy.screen_name) || screenName,\n        name: stringField(core.name) || stringField(legacy.name),\n        bio: stringField(result.profile_bio?.description) || stringField(legacy.description),\n        location: stringField(location.location) || stringField(legacy.location),","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/profile.js#L25-L61","documentation":"CommandExecutionError thrown by mapTwitterProfileResult when the raw API result for a profile is not a plain object — X returned something unexpected (an error payload, empty body, or guest-mode redirect) instead of the user object.","triggerScenarios":"Calling the `twitter profile` command where the UserByScreenName GraphQL response (or page-scraped equivalent) is not an object: error JSON, null, HTML error page parsed as string, or rate-limit response.","commonSituations":"X rate-limits the session and returns an error object; logged-out/guest fetch returns an HTML page; X API shape changes; account shadow-banned so the user lookup errors.","solutions":["Verify the browser session is logged in; re-run `opencli login`","Retry after a delay — rate limiting is a common cause of malformed payloads","Test whether the profile exists by visiting https://x.com/<handle> in the browser session","If the handle is valid and you're logged in but this persists, X likely changed the response shape; report/update the mapper"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isValidHandle(h) {\n  return typeof h === 'string' && /^@?[A-Za-z0-9_]{1,15}$/.test(h.trim());\n}\nif (!isValidHandle(username)) throw new Error('invalid handle');","typeGuard":"const isPlainObject = (v) =>\n  v !== null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"try {\n  const profile = await opencli('twitter profile', { username });\n} catch (e) {\n  if (e.name === 'CommandExecutionError' && /is malformed/.test(e.message)) {\n    await relogin(); // likely rate-limited or logged-out payload\n    return opencli('twitter profile', { username });\n  }\n  throw e;\n}","preventionTips":["Validate the handle format before calling","Keep the session logged in; logged-out fetches return malformed payloads","Back off on rate limits instead of hammering the API","Check the profile exists in-browser before programmatic lookups"],"tags":["twitter","api-response","schema"],"backgroundTag":"api-response-schema-mismatch","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}