paperclipai/paperclip · error · HarnessReconciliationError
codex_history_incomplete
codex_history_incomplete
Error message
codex_history_incomplete: ${method} omitted data What it means
pages() requires every page response from the history RPC to contain a data array. When the provider omits the data field, the library throws HarnessReconciliationError with code codex_history_incomplete rather than treating the missing data as an empty page, since a partial read cannot prove the thread is idle.
Source
Thrown at packages/paperclip-runner/src/drivers/codex/codex-history.ts:31
): Promise<Record<string, unknown>[]> {
const values = new Map<string, Record<string, unknown>>();
const cursors = new Set<string>();
let cursor: string | undefined;
for (let page = 0; page < 10_000; page += 1) {
let response: Record<string, unknown>;
try {
response = await transport.request(method, {
...params,
limit: 100,
...(cursor ? { cursor } : {}),
});
} catch (error) {
throw new HarnessReconciliationError(
`codex_history_read_failed: ${method} requires supported paginated history; ${String(error)}`,
);
}
if (!Array.isArray(response.data))
throw new HarnessReconciliationError(
`codex_history_incomplete: ${method} omitted data`,
);
for (const raw of response.data) {
const value = record(raw);
const id = identity(value);
if (!id)
throw new HarnessReconciliationError(
`codex_history_incomplete: ${method} omitted an identity`,
);
// Later pages can repeat the cursor anchor with its newly completed state.
values.set(id, value);
}
const next = response.nextCursor;
if (next == null) return [...values.values()];
if (typeof next !== "string" || !next || cursors.has(next)) {
throw new HarnessReconciliationError(
`codex_history_incomplete: ${method} repeated or invalid cursor`,
);View on GitHub (pinned to 01ad858492)
Solutions
- Pin or upgrade the Codex app-server to a version whose list methods return { data, nextCursor } envelopes.
- Log the full raw response to confirm the actual envelope shape and compare against the expected app-server protocol.
- If a proxy/wrapper sits in front of the app-server, fix it to pass through the response unchanged.
- Catch HarnessReconciliationError and fail the recovery run; never assume an empty history on this error.
Defensive patterns
Strategy: try-catch
Type guard
function isHistoryIncomplete(e: unknown): e is HarnessReconciliationError { return e instanceof HarnessReconciliationError && e.message.includes('codex_history_incomplete'); } Try / catch
try { const turns = await readCodexTurnMetadata(transport, threadId); } catch (e) { if (isHistoryIncomplete(e)) { reportReconciliationFailure(e); return null; } throw e; } Prevention
- Pin app-server and runner versions together
- Test the response envelope shape once at transport startup (expect { data, nextCursor })
- Avoid proxies that rewrite provider responses
- Treat envelope-shape drift as a deployment/upgrade signal
When it happens
Trigger: A thread/turns/list or thread/items/list response object has no array-valued data field — e.g. an app-server version returning a different envelope shape, or an error object returned as a successful response.
Common situations: Codex app-server API drift: a provider upgrade changed the response contract; a proxy or middleware stripping/renaming fields; mocking layers returning wrong shapes in tests.
Related errors
- codex_history_read_failed
- Unknown config key ${warning.path}; did you mean ${warning.s
- Unknown config key ${warning.path}; did you mean ${warning.s
- Worktree seed manifest is missing source path diagnostics.
- Unknown config key ${warning.path}; did you mean ${warning.s
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/84d97eff00bd137b.
Report an issue: GitHub.