jackwener/OpenCLI · error · CommandExecutionError
Twitter UserMedia returned malformed user result
Error message
Twitter UserMedia returned malformed user result
What it means
requireUserMediaPayload validates the UserMedia GraphQL response shape. After confirming there are no top-level errors, it requires payload.data.user.result to be a non-null object; if the user node is absent or null it throws 'malformed user result'. This guards against responses where Twitter returns no user entity for the requested screen name.
Source
Thrown at clis/twitter/download.js:245
function requireFetchPayload(value, context) {
const result = requireObjectPayload(unwrapBrowserResult(value), context);
if (result.ok === true) {
return result.payload;
}
if (result.ok === false) {
throwGraphqlFetchError(context, Number(result.status) || 0, typeof result.error === 'string' ? result.error : '');
}
throw new CommandExecutionError(`Twitter ${context} returned malformed fetch result`);
}
function requireUserMediaPayload(data) {
const payload = requireObjectPayload(data, 'UserMedia');
if (Array.isArray(payload.errors) && payload.errors.length > 0) {
throw new CommandExecutionError(`Twitter UserMedia returned GraphQL errors: ${JSON.stringify(payload.errors).slice(0, 200)}`);
}
const result = payload.data?.user?.result;
if (!result || typeof result !== 'object') {
throw new CommandExecutionError('Twitter UserMedia returned malformed user result');
}
const instructions = result.timeline_v2?.timeline?.instructions || result.timeline?.timeline?.instructions;
if (!Array.isArray(instructions)) {
throw new CommandExecutionError('Twitter UserMedia returned malformed timeline instructions');
}
return payload;
}
function parseUserMedia(data, seen) {
const items = [];
let nextCursor = null;
const result = requireUserMediaPayload(data).data.user.result;
const instructionSets = [
result.timeline_v2?.timeline?.instructions,
result.timeline?.timeline?.instructions,
].filter(Array.isArray);
const instructions = instructionSets.flat();
const visit = (value) => {View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the handle is correct and currently exists on x.com (check in a browser).
- Strip stray characters ('@', whitespace) — the CLI already trims and normalizes, but confirm the input.
- Re-run later if Twitter is having an incident returning incomplete payloads.
- Update the response parsing path if X changed the UserMedia response shape (data.user.result relocated).
Example fix
// before await opencli twitter download @thisuserdoesnotexist12345 --limit 5 // CommandExecutionError: Twitter UserMedia returned malformed user result // after: use a real handle await opencli twitter download @jack --limit 5
Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm handle exists before invoking
const exists = await fetch('https://x.com/' + handle).then(r => r.status !== 404);
if (!exists) throw new Error('Unknown handle: ' + handle); Type guard
function hasUserResult(payload) {
return !!payload
&& typeof payload === 'object'
&& !!payload.data
&& typeof payload.data.user?.result === 'object'
&& payload.data.user.result !== null;
} Try / catch
try {
await twitterDownload(username);
} catch (err) {
if (err instanceof CommandExecutionError && err.message.includes('malformed user result')) {
// treat as unknown/renamed handle: validate input and retry with corrected handle
} else throw err;
} Prevention
- Validate the handle (strip '@', trim, check non-empty) before invoking the CLI
- Confirm the account exists on x.com in a browser first
- Watch for X schema migrations that relocate data.user.result
- Treat this error as 'handle not found' and prompt for corrected input
When it happens
Trigger: The UserMedia response has data, data.user, or data.user.result missing/null — typically the screen name does not resolve to an existing account, or Twitter returned an empty user payload without a GraphQL errors array.
Common situations: Typo in the username or a renamed/deleted handle; passing '@' or empty after normalization; Twitter briefly returning incomplete payloads during incidents; endpoint schema changes moving the user node.
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 UserMedia returned malformed timeline instructions
- Twitter UserMedia returned GraphQL errors: ${JSON.stringify(
- Malformed Twitter follower: missing screen_name
- CreateList returned no list payload. Body: ${String(result.b
- CreateList returned a list payload without a numeric list id
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/755ae5f0bf4e5387.
Report an issue: GitHub.