jackwener/OpenCLI · error · CommandExecutionError
Malformed ChatGPT conversation payload for Deep Research ext
Error message
Malformed ChatGPT conversation payload for Deep Research extraction: missing mapping.
What it means
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.
Source
Thrown at clis/chatgpt/utils.js:1541
reportLength: report.length,
};
}
return buildDeepResearchProgressResult(widgetStateObject, pickFirstObject(responseMetadata), source);
}
function extractDeepResearchFromConversationPayload(payload, { expectedConversationId = '' } = {}) {
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
throw new CommandExecutionError('Malformed ChatGPT conversation payload for Deep Research extraction.');
}
const payloadConversationId = String(payload.conversation_id || payload.conversationId || payload.id || '').trim();
if (expectedConversationId && payloadConversationId && payloadConversationId !== expectedConversationId) {
throw new CommandExecutionError(
`ChatGPT conversation payload id mismatch: expected ${expectedConversationId}, got ${payloadConversationId}.`,
);
}
const mapping = payload?.mapping && typeof payload.mapping === 'object' ? payload.mapping : {};
if (!payload.mapping || typeof payload.mapping !== 'object' || Array.isArray(payload.mapping)) {
throw new CommandExecutionError('Malformed ChatGPT conversation payload for Deep Research extraction: missing mapping.');
}
const candidates = [];
for (const [messageId, node] of Object.entries(mapping)) {
const message = node?.message || {};
const metadata = message?.metadata || {};
const sdk = metadata?.chatgpt_sdk || {};
const responseMetadata = pickFirstObject(
sdk?.response_metadata,
sdk?.responseMetadata,
metadata?.response_metadata,
metadata?.responseMetadata,
);
let sawWidgetState = false;
for (const widgetState of [
sdk?.widget_state,
sdk?.widgetState,
metadata?.widget_state,
metadata?.widgetState,View on GitHub (pinned to 49907e53dc)
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
Example fix
// before
await extractDeepResearchFromConversationPayload(JSON.parse(text), { expectedConversationId });
// after
const payload = JSON.parse(text);
if (!payload || typeof payload.mapping !== 'object' || Array.isArray(payload.mapping)) {
throw new Error('Not a valid conversation payload: mapping missing');
}
await extractDeepResearchFromConversationPayload(payload, { expectedConversationId }); Defensive patterns
Strategy: validation
Validate before calling
function isValidConversationPayload(p) {
return !!p && typeof p === 'object' && p.mapping && typeof p.mapping === 'object' && !Array.isArray(p.mapping);
}
if (!isValidConversationPayload(payload)) throw new Error('payload.mapping missing — not a conversation payload'); Type guard
function isConversationPayload(p): p is { mapping: Record<string, { message?: unknown }> } {
return typeof p === 'object' && p !== null && 'mapping' in p
&& typeof (p as any).mapping === 'object' && !Array.isArray((p as any).mapping);
} Try / catch
try {
await extractDeepResearchFromConversationPayload(payload, { expectedConversationId });
} catch (e) {
if (String(e.message).includes('missing mapping')) {
// re-fetch the conversation or fall back to the network-entry path
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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'.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Malformed ChatGPT conversation network payload for ${entryCo
- chatgpt deep-research-result
- ChatGPT deep-research-result did not stay on requested conve
- ChatGPT deep-research-result conversation mismatch: expected
- chatgpt deep-research-result
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/51d65df175938072.
Report an issue: GitHub.