OpenHands/OpenHands · error · Error
Invalid conversation history response: expected page.items t
Error message
Invalid conversation history response: expected page.items to be an array.
What it means
Defensive guard inside useConversationHistory's queryFn: after EventService.searchEvents returns a page, the code asserts Array.isArray(page.items) before reversing. The agent-server contract is an EventSearchPage with an items array; a non-array means the response was malformed (wrong shape, null, or a cloud-proxy error envelope). Rather than crashing on .reverse() of undefined, the hook throws an explicit, grep-able error so React Query surfaces a failure.
Source
Thrown at src/hooks/query/use-conversation-history.ts:59
],
enabled: !!conversationId && !!conversation,
queryFn: async () => {
if (!conversationId) {
return { events: [], hasMore: false, nextPageId: null };
}
const page = await EventService.searchEvents(
conversationId,
conversation?.conversation_url ?? null,
conversation?.session_api_key ?? null,
{
limit: INITIAL_HISTORY_PAGE_SIZE,
sortOrder: "TIMESTAMP_DESC",
},
);
if (!Array.isArray(page.items)) {
throw new Error(
"Invalid conversation history response: expected page.items to be an array.",
);
}
// Reverse so callers can append in chronological order.
const events = [...page.items].reverse();
return {
events,
hasMore:
!!page.next_page_id || page.items.length >= INITIAL_HISTORY_PAGE_SIZE,
nextPageId: page.next_page_id ?? null,
};
},
// Keep the cached page so returning to a conversation renders the
// last-known discussion instantly (no skeleton). But refetch the tail on
// mount so events produced while we were away — e.g. an active /goal loop
// that keeps emitting user + agent turns while we're on another
// conversation — arrive in one batched REST page instead of beingView on GitHub (pinned to 500b4c533e)
Solutions
- Check the actual response body of GET /api/conversations/{id}/events in the browser network tab — confirm `items` exists and is an array.
- Verify the agent-server version satisfies compatibility.minimumAgentServer in config/defaults.json (assertAgentServerVersionIsSupported runs on bootstrap, not here, so a bypassed check is possible).
- If a custom ingress/proxy is in front of the agent-server, ensure it passes JSON bodies through unmodified.
- On the cloud path, confirm callCloudProxy unwraps error envelopes before they reach EventService.searchEvents.
Defensive patterns
Strategy: type-guard
Validate before calling
function isEventSearchPage(value: unknown): value is { items: unknown[]; next_page_id?: string | null } {
return typeof value === 'object' && value !== null && Array.isArray((value as any).items);
}
// const page = await EventService.searchEvents(...);
// if (!isEventSearchPage(page)) return { events: [], hasMore: false, nextPageId: null }; Type guard
function isValidHistoryPage(page: unknown): page is { items: import('#/types/agent-server/core').OpenHandsEvent[]; next_page_id?: string | null } {
return !!page && typeof page === 'object' && Array.isArray((page as { items?: unknown }).items);
} Prevention
- Log the raw response shape when this fires so backend drift is caught early.
- Keep the agent-server version pinned to compatibility.minimumAgentServer.
- Treat this error as a signal of response-shape drift, not a transient failure — do not blindly retry.
When it happens
Trigger: Initial REST history fetch (sort_order=TIMESTAMP_DESC, limit=50) returns a payload whose `items` field is not an array. Happens when: the cloud proxy returns an error object instead of a page; the agent-server returns a legacy/different shape after an upgrade; a middleware (ingress/proxy) rewrites the body; the response is an empty `null`.
Common situations: Agent-server version mismatch (frontend expects the new EventSearchPage shape); cloud proxy returning a 4xx/5xx error envelope that was not unwrapped; ingress returning its own error JSON; custom reverse proxy stripping the items field; response truncated by a body-size limit.
Related errors
- Invalid older-events response: expected page.items to be an
- Invalid transcript history response: expected page.items to
- No backend is configured.
- AGENT_SERVER_UNKNOWN_VERSION
- AGENT_SERVER_UNSUPPORTED_VERSION
AI-assisted analysis of OpenHands/OpenHands@500b4c533e (2026-08-12).
Data as JSON: /api/errors/7bc98080a589b4e7.
Report an issue: GitHub.