{"record":{"id":"e94c8e29731b5be3","repo":"can1357/oh-my-pi","slug":"v2-compaction-expected-exactly-one-compaction-outp","errorCode":null,"errorMessage":"V2 compaction expected exactly one compaction output item, got ${state.compactionItems.length} from ${state.outputItemCount} output items","messagePattern":"V2 compaction expected exactly one compaction output item, got (.+?) from (.+?) output items","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/compaction/compaction-v2-streaming.ts","lineNumber":532,"sourceCode":"\t\t\t}\n\t\t}\n\t\tdispatch();\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\n\treturn finishCompactionV2Collection(state, request);\n}\n\nfunction finishCompactionV2Collection(\n\tstate: CompactionV2CollectionState,\n\trequest: CompactionV2Request,\n): CompactionV2Response {\n\tif (!state.sawCompleted) {\n\t\tthrow new Error(\"V2 compaction stream closed before response.completed\");\n\t}\n\tif (state.compactionItems.length !== 1) {\n\t\tthrow new Error(\n\t\t\t`V2 compaction expected exactly one compaction output item, got ${state.compactionItems.length} from ${state.outputItemCount} output items`,\n\t\t);\n\t}\n\n\tconst compactionItem = state.compactionItems[0];\n\tconst { replacementHistory, retainedImageCount } = buildCompactionV2ReplacementHistory(\n\t\trequest.input,\n\t\tcompactionItem,\n\t\trequest.retainedMessageBudget,\n\t);\n\treturn {\n\t\tcompactionItem,\n\t\treplacementHistory,\n\t\tusedTokens: state.usage?.inputTokens ?? 0,\n\t\tusage: state.usage,\n\t\tretainedImageCount,\n\t};\n}","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/agent/src/compaction/compaction-v2-streaming.ts#L514-L550","documentation":"After the stream completes, finishCompactionV2Collection expects exactly one compaction-type output item among the response's output items; any other count means the server produced malformed or unexpected compaction output. The error reports how many compaction items were found and the total number of output items seen.","triggerScenarios":"The V2 compaction endpoint returns a completed response whose output items contain zero or multiple compaction items — e.g. API behavior change, wrong endpoint/deployment returning normal model output instead of a compaction item, or event filtering dropping/duplicating compaction events.","commonSituations":"Pointing at a regular Responses endpoint instead of the compaction endpoint; provider API version drift changing output item types; proxy rewriting responses; bugs after upgrading the server-side compaction model/deployment.","solutions":["Verify the endpoint is the dedicated compaction endpoint (correct base URL + compaction route/deployment), not a generic Responses endpoint","Log state.outputItemCount and event types to see what the server actually returned; compare against the expected compaction event schema","Pin/align the Azure OpenAI API version and deployment used for compaction after provider updates","Retry once in case of a transient server anomaly, then fall back to local compaction if it reproduces"],"exampleFix":"// before\nendpoint: \"https://res.openai.azure.com/openai/v1/responses\" // generic endpoint\n// after\nendpoint: getCompactionV2Endpoint(model) // compaction-specific endpoint/deployment","handlingStrategy":"validation","validationCode":"// verify you target the compaction endpoint, not a generic Responses endpoint\nconst endpoint = getCompactionV2Endpoint(model);\nif (!endpoint || !endpoint.includes(\"compaction\")) {\n  console.warn(\"unexpected compaction endpoint:\", endpoint);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await requestCompactionV2Streaming({ model, ... });\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"exactly one compaction output item\")) {\n    logServerEventsForDebugging(); // capture outputItemCount/types\n    return compactLocally(session); // deterministic fallback\n  }\n  throw err;\n}","preventionTips":["Point at the dedicated compaction endpoint/deployment, never a generic Responses route","Pin the provider API version and re-verify after upgrades","Log SSE event types when counts deviate; fall back to local compaction"],"tags":["compaction","protocol","openai","unexpected-response"],"backgroundTag":"unexpected-response-shape","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}