{"record":{"id":"de6f0deb7283546b","repo":"jackwener/OpenCLI","slug":"malformed-source-payload","errorCode":null,"errorMessage":"`Malformed ${source} payload`","messagePattern":"`Malformed (.+?) payload`","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/youtube/transcript.js","lineNumber":33,"sourceCode":"import { CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\n\nfunction unwrapBrowserResult(value) {\n    if (value && typeof value === 'object' && 'session' in value && 'data' in value) {\n        return value.data;\n    }\n    return value;\n}\n\nfunction normalizeSegmentsPayload(value, source, { allowNull = false } = {}) {\n    const payload = unwrapBrowserResult(value);\n    if (payload == null && allowNull)\n        return null;\n    if (Array.isArray(payload))\n        return payload;\n    if (payload && typeof payload === 'object' && payload.error) {\n        throw new CommandExecutionError(String(payload.error));\n    }\n    throw new CommandExecutionError(`Malformed ${source} payload`);\n}\n\nfunction parseJson3Segments(text) {\n    let data;\n    try {\n        data = JSON.parse(text);\n    }\n    catch (err) {\n        throw new CommandExecutionError(`Malformed json3 timedtext response: ${err?.message || err}`);\n    }\n    if (!Array.isArray(data?.events)) {\n        throw new CommandExecutionError('Malformed json3 timedtext response: missing events array');\n    }\n    const rows = [];\n    for (const event of data.events) {\n        const startMs = Number(event?.tStartMs || 0);\n        const durMs = Number(event?.dDurationMs || 0);\n        const segs = Array.isArray(event?.segs) ? event.segs : [];","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/transcript.js#L15-L51","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst segments = normalizeSegmentsPayload(playerResult, 'player caption extraction', { allowNull: true });\n// after\nif (playerResult == null || Array.isArray(playerResult) || (playerResult && typeof playerResult === 'object')) {\n  // proceed\n} else {\n  console.error('unexpected payload shape from browser context');\n}","handlingStrategy":"type-guard","validationCode":"const unwrapped = unwrapBrowserResult(value);\nif (unwrapped != null && !Array.isArray(unwrapped) && (typeof unwrapped !== 'object' || !('error' in unwrapped))) {\n  // acceptable only if it matches one of the expected shapes; otherwise abort early\n}","typeGuard":"function isKnownPayloadShape(v) {\n  return v == null || Array.isArray(v) || (typeof v === 'object' && !Array.isArray(v));\n}","tryCatchPattern":"try {\n  const segments = normalizeSegmentsPayload(playerResult, 'player caption extraction', { allowNull: true });\n} catch (err) {\n  if (/Malformed .* payload/.test(err.message)) {\n    console.error('unrecognized payload shape from browser; reloading page');\n  }\n}","preventionTips":["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"],"tags":["youtube","browser-automation","schema-validation","malformed-payload"],"backgroundTag":"malformed-response-payload","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}