jackwener/OpenCLI · error · CommandExecutionError
${context} returned a malformed result.
Error message
${context} returned a malformed result. What it means
requirePostActionResult validates every value returned from page.evaluate() inside the twitter post CLI. If the unwrapped browser result is not a plain object with a boolean `ok` field (e.g. null, an array, undefined, or a non-object), the helper throws this CommandExecutionError prefixed with the caller-provided context string. It exists to catch browser-side scripts that silently returned nothing or returned an unexpected shape instead of the { ok: boolean } contract.
Source
Thrown at clis/twitter/post.js:47
}
const stat = fs.statSync(absPath, { throwIfNoEntry: false });
if (!stat || !stat.isFile()) {
throw new CommandExecutionError(`Not a valid file: ${absPath}`);
}
return absPath;
});
}
function isUnsupportedInsertTextError(err) {
const msg = err instanceof Error ? err.message : String(err);
const lower = msg.toLowerCase();
return lower.includes('unknown action') || lower.includes('not supported') || lower.includes('inserttext returned no inserted flag');
}
function requirePostActionResult(value, context) {
const result = unwrapBrowserResult(value);
if (!result || typeof result !== 'object' || Array.isArray(result) || typeof result.ok !== 'boolean') {
throw new CommandExecutionError(`${context} returned a malformed result.`);
}
if (Object.prototype.hasOwnProperty.call(result, 'message') && result.message != null && typeof result.message !== 'string') {
throw new CommandExecutionError(`${context} returned a malformed message.`);
}
if (Object.prototype.hasOwnProperty.call(result, 'error') && result.error != null && typeof result.error !== 'string') {
throw new CommandExecutionError(`${context} returned a malformed error.`);
}
return result;
}
function validateSubmitStatusPair(result) {
if ((result.id && !result.url) || (!result.id && result.url)) {
throw new CommandExecutionError('Twitter post completion returned only one of id/url.');
}
if (!result.id && !result.url) return;
if (typeof result.id !== 'string' || !/^\d+$/.test(result.id)) {
throw new CommandExecutionError('Twitter post completion returned a malformed status id.');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command on a fresh, loaded x.com page — transient evaluate failures usually resolve on retry
- Update the twitter CLI if X changed its DOM, since the in-page script may be crashing before it can return { ok }
- Log the raw value passed to requirePostActionResult to see what unwrapBrowserResult received
- Ensure no navigation, alert dialogs, or redirects interrupt the composer page while the command runs
Example fix
// before: raw evaluate result fed straight in
const result = requirePostActionResult(await page.evaluate(script), 'Focus composer');
// after: guard against undefined/null before validating
const raw = await page.evaluate(script);
if (raw == null) throw new CommandExecutionError('Focus composer: page returned nothing (reload and retry).');
const result = requirePostActionResult(raw, 'Focus composer'); Defensive patterns
Strategy: type-guard
Validate before calling
function isPlainPostResult(v) { return v != null && typeof v === 'object' && !Array.isArray(v) && typeof v.ok === 'boolean'; }
if (!isPlainPostResult(raw)) throw new Error('browser returned malformed result; reload page and retry'); Type guard
function isPostActionResult(v) { return typeof v === 'object' && v !== null && !Array.isArray(v) && 'ok' in v && typeof v.ok === 'boolean'; } Try / catch
try {
const result = requirePostActionResult(await page.evaluate(script), 'Focus composer');
} catch (e) {
if (String(e.message).includes('returned a malformed result')) { await page.reload(); return retry(); }
throw e;
} Prevention
- Reload the x.com page before posting if the tab has been open a long time
- Avoid navigating or closing dialogs while a post command runs
- Log raw evaluate results when debugging DOM changes
- Keep the CLI updated against current X DOM structure
When it happens
Trigger: Any of focusComposer, verifyComposerText, insertComposerText, waitForImageUpload, upload, or clickResult passing an evaluate() result through requirePostActionResult where unwrapBrowserResult yields null/undefined, an Array, a non-object, or an object whose `ok` property is not a boolean — typically because the page script threw before returning, the page navigated mid-evaluate, or the injected script's return was serialized away.
Common situations: X/Twitter DOM or bundle changes causing the in-page IIFE to crash before returning; page navigation or dialog closing during evaluate; a browser extension or CSP blocking script execution so evaluate returns undefined; running against a stale/closed tab where evaluate resolves to undefined.
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
- ${context} returned a malformed message.
- ${context} returned a malformed error.
- Twitter post completion returned only one of id/url.
- Twitter post completion returned a malformed status id.
- Twitter post completion returned a malformed status url.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8a98a2ee01ce726f.
Report an issue: GitHub.