{"record":{"id":"9e86a5dbce9eeae7","repo":"jackwener/OpenCLI","slug":"malformed-chatgpt-conversation-network-payload-for","errorCode":null,"errorMessage":"Malformed ChatGPT conversation network payload for ${entryConversationId || 'unknown conversation'}.","messagePattern":"Malformed ChatGPT conversation network payload for (.+?)\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/utils.js","lineNumber":1599,"sourceCode":"    candidates.sort((a, b) => deepResearchCandidateScore(b) - deepResearchCandidateScore(a));\n    return candidates[0] || null;\n}\n\nfunction conversationIdFromBackendConversationUrl(url) {\n    const match = String(url || '').match(/\\/backend-api\\/conversation\\/([^/?#]+)/);\n    return match?.[1] ? decodeURIComponent(match[1]) : '';\n}\n\nfunction extractDeepResearchFromNetworkEntries(entries, { expectedConversationId = '' } = {}) {\n    const candidates = [];\n    for (const entry of Array.isArray(entries) ? entries : []) {\n        const url = String(entry?.url || '');\n        if (!/\\/backend-api\\/conversation\\//.test(url)) continue;\n        const entryConversationId = conversationIdFromBackendConversationUrl(url);\n        if (expectedConversationId && entryConversationId !== expectedConversationId) continue;\n        const body = parseJsonMaybe(entry?.responsePreview) || parseJsonMaybe(entry?.body) || null;\n        if (!body) {\n            throw new CommandExecutionError(`Malformed ChatGPT conversation network payload for ${entryConversationId || 'unknown conversation'}.`);\n        }\n        const extracted = extractDeepResearchFromConversationPayload(body, { expectedConversationId });\n        if (extracted) {\n            candidates.push({\n                ...extracted,\n                method: extracted.status === 'completed'\n                    ? 'network-conversation-widget-state'\n                    : 'network-conversation-widget-progress',\n                networkUrl: url,\n            });\n        }\n    }\n    candidates.sort((a, b) => deepResearchCandidateScore(b) - deepResearchCandidateScore(a));\n    return candidates[0] || null;\n}\n\nfunction conversationIdFromUrl(url) {\n    const match = String(url || '').match(/\\/c\\/([a-zA-Z0-9_-]+)/);","sourceCodeStart":1581,"sourceCodeEnd":1617,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/utils.js#L1581-L1617","documentation":"Thrown when scanning captured network entries for a Deep Research conversation: an entry whose URL matches backend-api/conversation/<id> has no parseable response body. The library needs the JSON conversation payload from that network entry to extract results.","triggerScenarios":"A network entry matching the conversation URL was recorded but both entry.responsePreview and entry.body are missing, empty, or unparseable JSON (parseJsonMaybe returns null).","commonSituations":"Response body streaming not captured (response body already consumed or preview truncated); binary/HTML error page recorded instead of JSON; HAR export with response bodies stripped; navigation cleared the buffer mid-response.","solutions":["Ensure network capture records response bodies (responsePreview/body) for backend-api/conversation requests","Check the entry body is JSON and not an HTML error page or empty 204/304 response","Re-run the request so the network entry is captured fresh, or extract via the page payload path instead","Increase capture buffer/preview size if the body is being truncated"],"exampleFix":"// before\nconst body = parseJsonMaybe(entry.responsePreview);\nawait extractDeepResearchFromConversationPayload(body, { expectedConversationId });\n// after\nconst body = parseJsonMaybe(entry?.responsePreview) || parseJsonMaybe(entry?.body);\nif (!body) throw new Error('conversation network entry had no JSON body; re-capture with bodies enabled');\nawait extractDeepResearchFromConversationPayload(body, { expectedConversationId });","handlingStrategy":"validation","validationCode":"const body = parseJsonMaybe(entry?.responsePreview) || parseJsonMaybe(entry?.body);\nif (!body || !body.mapping) throw new Error('network entry has no usable conversation JSON — re-capture with response bodies');","typeGuard":"function hasResponseBody(e) { return typeof e === 'object' && e !== null && (typeof e.responsePreview === 'string' || typeof e.body === 'string'); }","tryCatchPattern":"try {\n  await waitForChatGPTDeepResearchResult(/* ... */);\n} catch (e) {\n  if (String(e.message).startsWith('Malformed ChatGPT conversation network payload')) {\n    // retry capture or extract from the page payload instead\n  } else throw e;\n}","preventionTips":["Enable network capture of response bodies (HAR with content, or CDP response body interception)","Skip entries with empty/HTML bodies before extraction instead of treating every URL match as extractable","Re-run capture fresh; stale buffers after navigation lose bodies"],"tags":["chatgpt","network","payload-validation","deep-research"],"backgroundTag":"missing-response-body","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}