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

  1. Verify the handle is correct and currently exists on x.com (check in a browser).
  2. Strip stray characters ('@', whitespace) — the CLI already trims and normalizes, but confirm the input.
  3. Re-run later if Twitter is having an incident returning incomplete payloads.
  4. 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

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

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/755ae5f0bf4e5387. Report an issue: GitHub.