jackwener/OpenCLI · error · CommandExecutionError
`Malformed ${source} payload`
Error message
`Malformed ${source} payload` What it means
normalizeSegmentsPayload throws this when the unwrapped browser result is neither null, an array, nor an object carrying an `error` field — i.e. the payload shape is unrecognizable. The `source` label (e.g. 'player caption extraction') is interpolated into the message to identify which extraction step produced the bad payload.
Source
Thrown at clis/youtube/transcript.js:33
import { CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
function unwrapBrowserResult(value) {
if (value && typeof value === 'object' && 'session' in value && 'data' in value) {
return value.data;
}
return value;
}
function normalizeSegmentsPayload(value, source, { allowNull = false } = {}) {
const payload = unwrapBrowserResult(value);
if (payload == null && allowNull)
return null;
if (Array.isArray(payload))
return payload;
if (payload && typeof payload === 'object' && payload.error) {
throw new CommandExecutionError(String(payload.error));
}
throw new CommandExecutionError(`Malformed ${source} payload`);
}
function parseJson3Segments(text) {
let data;
try {
data = JSON.parse(text);
}
catch (err) {
throw new CommandExecutionError(`Malformed json3 timedtext response: ${err?.message || err}`);
}
if (!Array.isArray(data?.events)) {
throw new CommandExecutionError('Malformed json3 timedtext response: missing events array');
}
const rows = [];
for (const event of data.events) {
const startMs = Number(event?.tStartMs || 0);
const durMs = Number(event?.dDurationMs || 0);
const segs = Array.isArray(event?.segs) ? event.segs : [];View on GitHub (pinned to 49907e53dc)
Solutions
- Identify which `source` appears in the message and inspect that extraction step's injected script against current YouTube DOM.
- Update the CLI so its injected scripts match the current YouTube page structure.
- Retry with a fresh browser page/session to rule out transient navigation or half-loaded pages.
- Confirm the video URL is a valid watch URL (not a channel/shorts redirect) before invoking extraction.
Example fix
// before
const segments = normalizeSegmentsPayload(playerResult, 'player caption extraction', { allowNull: true });
// after
if (playerResult == null || Array.isArray(playerResult) || (playerResult && typeof playerResult === 'object')) {
// proceed
} else {
console.error('unexpected payload shape from browser context');
} Defensive patterns
Strategy: type-guard
Validate before calling
const unwrapped = unwrapBrowserResult(value);
if (unwrapped != null && !Array.isArray(unwrapped) && (typeof unwrapped !== 'object' || !('error' in unwrapped))) {
// acceptable only if it matches one of the expected shapes; otherwise abort early
} Type guard
function isKnownPayloadShape(v) {
return v == null || Array.isArray(v) || (typeof v === 'object' && !Array.isArray(v));
} Try / catch
try {
const segments = normalizeSegmentsPayload(playerResult, 'player caption extraction', { allowNull: true });
} catch (err) {
if (/Malformed .* payload/.test(err.message)) {
console.error('unrecognized payload shape from browser; reloading page');
}
} Prevention
- Reload or re-navigate the page if evaluate returns undefined
- Check for consent walls before running injected scripts
- Log unexpected payload shapes (JSON.stringify) for debugging
- Pin a working CLI version and test against YouTube changes
When it happens
Trigger: `segments` -> `normalizeSegmentsPayload` receives an object without `error` and not an array — e.g. page.evaluate returned undefined/{} because the injected script hit an exception silently, or returned an unexpected wrapper object after a YouTube page change.
Common situations: YouTube changing the player response shape; the injected script returning undefined on pages where the player API is absent; consent/cookie walls causing partial page loads; browser tab navigated away mid-evaluation.
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
- Malformed caption info payload
- Malformed json3 timedtext response: missing events array
- Booking.com extractor returned malformed items
- Instagram media metadata returned malformed result
- Sales Navigator messaging thread API returned malformed payl
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/de6f0deb7283546b.
Report an issue: GitHub.