jackwener/OpenCLI · error · CommandExecutionError

Twitter profile response payload is malformed

Error message

Twitter profile response payload is malformed

What it means

CommandExecutionError thrown when the result of the in-page fetch of the UserByScreenName GraphQL endpoint is not a plain object. The library expects the page.evaluate payload to be an object like {ok, result, ...}; anything else (null, array, primitive) means the response pipeline broke rather than a normal API outcome.

Source

Thrown at clis/twitter/profile.js:168

            httpStatus: resp.status,
            error: 'HTTP ' + resp.status,
            hint: 'User may not exist, auth may be required, or queryId expired'
          };
        }
        let d;
        try {
          d = await resp.json();
        } catch (error) {
          return {ok: false, error: 'Twitter profile response was not JSON: ' + String(error && error.message || error)};
        }

        const result = d.data?.user?.result;
        if (!result) return {ok: false, notFound: true, error: 'User @' + screenName + ' not found'};
        return {ok: true, result};
      }
    `));
        if (!isPlainObject(rawResult)) {
            throw new CommandExecutionError('Twitter profile response payload is malformed');
        }
        if (!rawResult.ok) {
            // For HTTP errors, use fork's rich code mapping (429/401/403/404/5xx differentiation
            // from describeTwitterApiError); fall back to the plain message for non-HTTP failures
            // (fetch threw, JSON parse failed, payload malformed).
            const message = typeof rawResult.httpStatus === 'number'
                ? describeTwitterApiError('UserByScreenName', rawResult.httpStatus, rawResult.hint)
                : rawResult.error + (rawResult.hint ? ` (${rawResult.hint})` : '');
            if (rawResult.auth) {
                throw new AuthRequiredError('x.com', message);
            }
            if (rawResult.notFound) {
                throw new EmptyResultError('twitter profile', message);
            }
            throw new CommandExecutionError(message);
        }
        return mapTwitterProfileResult(rawResult.result, username);
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command once to rule out a transient page-context failure
  2. Check for x.com API/GraphQL envelope changes and update the library version
  3. Disable browser extensions or anti-bot interference in the automation profile
  4. Wrap the call in try-catch for CommandExecutionError and fall back to re-initializing the page before retrying
Defensive patterns

Strategy: type-guard

Type guard

function isPlainObject(v) {
  return v !== null && typeof v === 'object' && !Array.isArray(v);
}

Try / catch

try {
  const profile = await cli.run('twitter profile', { username });
} catch (e) {
  if (e instanceof CommandExecutionError && /malformed/.test(e.message)) {
    await reopenPage(); // fresh page context
    return cli.run('twitter profile', { username });
  }
  throw e;
}

Prevention

When it happens

Trigger: page.evaluate returns a non-object — e.g. the injected script threw and returned undefined, the fetch wrapper was overridden in page context, or unwrapBrowserResult yielded null because the browser returned a wrapped/unexpected value.

Common situations: x.com changed its GraphQL response envelope (breaking change); an extension or anti-bot script corrupts window state; the evaluate string is built with older quoting/serialization; headless environment blocks fetch so the promise resolves to undefined.

Understand the failure class

Related errors


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