jackwener/OpenCLI · error · CommandExecutionError
Twitter profile response for @${screenName} is malformed
Error message
Twitter profile response for @${screenName} is malformed What it means
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.
Source
Thrown at clis/twitter/profile.js:43
function isPlainObject(value) {
return value != null && typeof value === 'object' && !Array.isArray(value);
}
function stringField(value) {
return typeof value === 'string' ? value : '';
}
function countField(...values) {
for (const value of values) {
if (typeof value === 'number' && Number.isFinite(value))
return value;
}
return 0;
}
export function mapTwitterProfileResult(result, screenName) {
if (!isPlainObject(result)) {
throw new CommandExecutionError(`Twitter profile response for @${screenName} is malformed`);
}
const hasLegacy = isPlainObject(result.legacy);
const hasCore = isPlainObject(result.core);
if (!hasLegacy && !hasCore) {
throw new CommandExecutionError(`Twitter profile response for @${screenName} is missing profile fields`);
}
const legacy = hasLegacy ? result.legacy : {};
const core = hasCore ? result.core : {};
if (!stringField(core.screen_name) && !stringField(legacy.screen_name) && !stringField(core.name) && !stringField(legacy.name) && !stringField(core.created_at) && !stringField(legacy.created_at)) {
throw new CommandExecutionError(`Twitter profile response for @${screenName} is missing profile identity fields`);
}
const location = isPlainObject(result.location) ? result.location : {};
const expandedUrl = stringField(result.website?.url) || stringField(legacy.entities?.url?.urls?.[0]?.expanded_url);
return [{
screen_name: stringField(core.screen_name) || stringField(legacy.screen_name) || screenName,
name: stringField(core.name) || stringField(legacy.name),
bio: stringField(result.profile_bio?.description) || stringField(legacy.description),
location: stringField(location.location) || stringField(legacy.location),View on GitHub (pinned to 49907e53dc)
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
Defensive patterns
Strategy: validation
Validate before calling
function isValidHandle(h) {
return typeof h === 'string' && /^@?[A-Za-z0-9_]{1,15}$/.test(h.trim());
}
if (!isValidHandle(username)) throw new Error('invalid handle'); Type guard
const isPlainObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
Try / catch
try {
const profile = await opencli('twitter profile', { username });
} catch (e) {
if (e.name === 'CommandExecutionError' && /is malformed/.test(e.message)) {
await relogin(); // likely rate-limited or logged-out payload
return opencli('twitter profile', { username });
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Twitter profile response for @${screenName} is missing profi
- Twitter profile response for @${screenName} is missing profi
- 字幕条目缺少 subtitle_url 字段
- Twitter device-follow response was missing the expected time
- Twitter device-follow entries could not be joined to tweet/u
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4ded77777e8457c4.
Report an issue: GitHub.