{"record":{"id":"51d65df175938072","repo":"jackwener/OpenCLI","slug":"malformed-chatgpt-conversation-payload-for-deep-re-51d65d","errorCode":null,"errorMessage":"Malformed ChatGPT conversation payload for Deep Research extraction: missing mapping.","messagePattern":"Malformed ChatGPT conversation payload for Deep Research extraction: missing mapping\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/utils.js","lineNumber":1541,"sourceCode":"            reportLength: report.length,\n        };\n    }\n    return buildDeepResearchProgressResult(widgetStateObject, pickFirstObject(responseMetadata), source);\n}\n\nfunction extractDeepResearchFromConversationPayload(payload, { expectedConversationId = '' } = {}) {\n    if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n        throw new CommandExecutionError('Malformed ChatGPT conversation payload for Deep Research extraction.');\n    }\n    const payloadConversationId = String(payload.conversation_id || payload.conversationId || payload.id || '').trim();\n    if (expectedConversationId && payloadConversationId && payloadConversationId !== expectedConversationId) {\n        throw new CommandExecutionError(\n            `ChatGPT conversation payload id mismatch: expected ${expectedConversationId}, got ${payloadConversationId}.`,\n        );\n    }\n    const mapping = payload?.mapping && typeof payload.mapping === 'object' ? payload.mapping : {};\n    if (!payload.mapping || typeof payload.mapping !== 'object' || Array.isArray(payload.mapping)) {\n        throw new CommandExecutionError('Malformed ChatGPT conversation payload for Deep Research extraction: missing mapping.');\n    }\n    const candidates = [];\n    for (const [messageId, node] of Object.entries(mapping)) {\n        const message = node?.message || {};\n        const metadata = message?.metadata || {};\n        const sdk = metadata?.chatgpt_sdk || {};\n        const responseMetadata = pickFirstObject(\n            sdk?.response_metadata,\n            sdk?.responseMetadata,\n            metadata?.response_metadata,\n            metadata?.responseMetadata,\n        );\n        let sawWidgetState = false;\n        for (const widgetState of [\n            sdk?.widget_state,\n            sdk?.widgetState,\n            metadata?.widget_state,\n            metadata?.widgetState,","sourceCodeStart":1523,"sourceCodeEnd":1559,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/utils.js#L1523-L1559","documentation":"Thrown during Deep Research extraction when a ChatGPT conversation payload lacks a valid 'mapping' object. The mapping is the node graph that holds all conversation messages; without it no extraction is possible, so the library fails fast instead of returning empty results.","triggerScenarios":"extractDeepResearchFromConversationPayload is called with a payload where payload.mapping is missing, not an object, or is an array — e.g. a truncated or non-conversation JSON body was passed, or an API shape change removed/renamed 'mapping'.","commonSituations":"Passing a saved conversation export that is actually an error object or HTML-converted JSON; calling with response JSON from a non-conversation endpoint; upstream ChatGPT schema changes; hand-crafted fixtures in tests missing mapping.","solutions":["Inspect the payload and confirm it is a real backend-api/conversation JSON body containing a 'mapping' key","Re-fetch the conversation and pass response.json() (the raw object), not a wrapped or partial object","Validate payload.mapping is a non-array object before calling the extractor","If upstream changed the schema, update the extraction code to the new field layout"],"exampleFix":"// before\nawait extractDeepResearchFromConversationPayload(JSON.parse(text), { expectedConversationId });\n// after\nconst payload = JSON.parse(text);\nif (!payload || typeof payload.mapping !== 'object' || Array.isArray(payload.mapping)) {\n  throw new Error('Not a valid conversation payload: mapping missing');\n}\nawait extractDeepResearchFromConversationPayload(payload, { expectedConversationId });","handlingStrategy":"validation","validationCode":"function isValidConversationPayload(p) {\n  return !!p && typeof p === 'object' && p.mapping && typeof p.mapping === 'object' && !Array.isArray(p.mapping);\n}\nif (!isValidConversationPayload(payload)) throw new Error('payload.mapping missing — not a conversation payload');","typeGuard":"function isConversationPayload(p): p is { mapping: Record<string, { message?: unknown }> } {\n  return typeof p === 'object' && p !== null && 'mapping' in p\n    && typeof (p as any).mapping === 'object' && !Array.isArray((p as any).mapping);\n}","tryCatchPattern":"try {\n  await extractDeepResearchFromConversationPayload(payload, { expectedConversationId });\n} catch (e) {\n  if (String(e.message).includes('missing mapping')) {\n    // re-fetch the conversation or fall back to the network-entry path\n  } else throw e;\n}","preventionTips":["Always pass the raw JSON body of a backend-api/conversation response","Assert payload.mapping exists in fixtures/tests before running extraction","Log payload keys when extraction fails to detect upstream schema changes early"],"tags":["chatgpt","payload-validation","deep-research","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}