can1357/oh-my-pi · error
OpenAI Responses compaction input contains a non-object item
Error message
OpenAI Responses compaction input contains a non-object item
What it means
When preparing OpenAI Responses input for compaction, every input item must be a plain object (Record<string, unknown>); the code validates each item after transforming the session history and throws if any element is not an object. This catches corrupted or wrongly-shaped history before it is sent to the API.
Source
Thrown at packages/agent/src/compaction/compaction.ts:1459
function buildOpenAiResponsesCompactionInput(
messages: Message[],
model: Model<"openai-responses" | "azure-openai-responses" | "openai-codex-responses">,
previousReplacementHistory: Array<Record<string, unknown>> | undefined,
): Array<Record<string, unknown>> {
const input = buildResponsesInput({
model,
context: { messages },
strictResponsesPairing: model.compat.strictResponsesPairing,
supportsImageDetailOriginal: openAiCompatSupportsImageDetailOriginal(model),
nativeHistory: { replay: true, filterReasoning: false },
includeThinkingSignatures: true,
repairOrphanOutputs: true,
});
const nativeInput: Array<Record<string, unknown>> = [];
for (const item of input) {
if (!isRecord(item)) {
throw new Error("OpenAI Responses compaction input contains a non-object item");
}
nativeInput.push(item);
}
return stripOpenAIResponsesOutputOnlyStatusesForReplay(
previousReplacementHistory ? [...previousReplacementHistory, ...nativeInput] : nativeInput,
);
}
/**
* Resolve the Responses `reasoning` param for a V2 compaction request the same
* way a normal turn does — through {@link resolveOpenAICompatPolicy}, so it
* honors per-model effort support, `omitReasoningEffort`, disable modes, and the
* wire-effort mapping. Returns `undefined` for non-reasoning models or when the
* user selected `Off` (matching the normal-turn omission, not a fabricated shape).
*/
function buildCompactionV2Reasoning(
model: Model<"openai-responses" | "azure-openai-responses" | "openai-codex-responses">,
thinkingLevel: ThinkingLevel | undefined,View on GitHub (pinned to 9690622007)
Solutions
- Inspect the session history/messages feeding the compaction for non-object entries (null, string, number) and fix or remove them
- Validate/normalize items before compaction — ensure each message passes the provider's input transform and remains an object
- If a converter or plugin mutates input, fix it to emit record-shaped items matching the OpenAI Responses input schema
- Re-export or rebuild the session from its source if the stored history is corrupted
Example fix
// before
input.push("summarize this") // raw string item
// after
input.push({ role: "user", content: [{ type: "input_text", text: "summarize this" }] }) Defensive patterns
Strategy: validation
Validate before calling
const bad = input.findIndex((item) => item === null || typeof item !== "object");
if (bad !== -1) {
throw new Error(`input[${bad}] is not an object: ${JSON.stringify(input[bad])}`);
} Type guard
function isRecord(v: unknown): v is Record<string, unknown> {
return typeof v === "object" && v !== null && !Array.isArray(v);
} Try / catch
try {
await compact(session);
} catch (err) {
if (err instanceof Error && err.message.includes("non-object item")) {
sanitizeHistory(session); // drop/normalize malformed entries
return compact(session);
}
throw err;
} Prevention
- Normalize every history item through the provider input transform before compaction
- Reject/repair string or null message items at session load time
- Add a record-shape type guard at the boundary where custom plugins inject messages
When it happens
Trigger: The serialized/transformed session input array contains a non-object element — e.g. a raw string, number, null, or undefined item introduced by a custom session format, a buggy converter/filter upstream, or hand-edited/corrupted session JSONL.
Common situations: Custom message transforms or plugins pushing plain strings into the input array; older session files with a different message schema merged into a new-format session; scripts that patch session history and insert raw text items.
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.
Related errors
- Model ${model.id} does not support V2 streaming compaction
- V2 remote compaction failed (${response.status} ${response.s
- V2 compaction expected exactly one compaction output item, g
- formatCompactionV2Failure(event, type)
- OpenAI Files API returned an invalid upload response
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/83b8441df792bc3b.
Report an issue: GitHub.