openclaw/openclaw · warning · Error
Pi session list parameters must be an object
Error message
Pi session list parameters must be an object
What it means
Thrown by parseListParams when the list parameters value is supplied (not undefined/null) but is not a plain object (record). Arrays, strings, numbers, booleans, and any non-record primitive are rejected. The catalog list path requires either no params (defaults) or a record with the recognised keys.
Source
Thrown at extensions/acpx/src/pi-session-catalog.ts:165
}
if (part.type === "text" && typeof part.text === "string") {
return [part.text];
}
if (part.type === "image") {
const mimeType = optionalPiString(part.mimeType, 128);
return [mimeType ? `[image: ${mimeType}]` : "[image]"];
}
return [];
})
.join("\n");
}
function parseListParams(value: unknown): { searchTerm?: string; limit: number; cursor?: string } {
if (value === undefined || value === null) {
return { limit: DEFAULT_PAGE_LIMIT };
}
if (!isRecord(value)) {
throw new Error("Pi session list parameters must be an object");
}
const unknown = Object.keys(value).find(
(key) => !["searchTerm", "limit", "cursor"].includes(key),
);
if (unknown) {
throw new Error(`unknown Pi session list parameter: ${unknown}`);
}
const searchTerm = optionalPiString(value.searchTerm, MAX_SEARCH_LENGTH);
if (value.searchTerm !== undefined && !searchTerm) {
throw new Error("searchTerm is invalid");
}
const cursor = optionalRawCursor(value.cursor);
return {
limit: boundedLimit(value.limit),
...(searchTerm ? { searchTerm } : {}),
...(cursor ? { cursor } : {}),
};
}View on GitHub (pinned to 01804a7531)
Solutions
- Pass either undefined (defaults) or a plain object with keys from { searchTerm, limit, cursor }.
- If you received params as JSON, parse it first: JSON.parse(paramsJSON).
- Wrap bare values: use { searchTerm: value } instead of value.
- Validate with isRecord at the boundary before calling list.
Example fix
// before await listLocalPiSessionPage(req.body); // body is a JSON string // after await listLocalPiSessionPage(JSON.parse(req.body));
Defensive patterns
Strategy: type-guard
Validate before calling
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
function coerceListParams(value: unknown) {
if (value === undefined || value === null) return undefined;
if (!isRecord(value)) throw new TypeError("Pi session list parameters must be an object");
return value;
} Type guard
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
function isPiListParams(value: unknown): value is Record<string, unknown> {
return value === undefined || value === null || isRecord(value);
} Prevention
- Parse JSON params before passing them to listLocalPiSessionPage.
- Pass undefined for defaults rather than a stringified object.
- Validate with isRecord at the boundary.
When it happens
Trigger: Calling listLocalPiSessionPage with a JSON string instead of a parsed object. Passing an array of params. Passing a primitive (e.g. a bare search string) instead of { searchTerm: string }. A serialisation layer forgot to JSON.parse before invoking.
Common situations: A node-command handler receives paramsJSON and the caller forgets to parse it into an object. A REST/IPC boundary sends the params as a JSON string. A naive client passes the search term directly instead of wrapping it.
Related errors
- unknown Pi session list parameter: ${unknown}
- searchTerm is invalid
- Pi session catalog hostId is invalid
- hostId is invalid
- limit must be an integer between 1 and ${String(MAX_PAGE_LIM
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/73beba78e736fc86.
Report an issue: GitHub.