can1357/oh-my-pi · error
RPC message page limit must be between 1 and ${MAX_RPC_MESSA
Error message
RPC message page limit must be between 1 and ${MAX_RPC_MESSAGE_PAGE_LIMIT} What it means
pageRpcMessages validates the limit option: it must be a safe integer between 1 and 256 (MAX_RPC_MESSAGE_PAGE_LIMIT). Passing undefined uses the default (100); anything outside the range — 0, negative, non-integers, NaN, or >256 — throws this error.
Source
Thrown at packages/coding-agent/src/modes/rpc/rpc-messages.ts:102
function sameSnapshot(cursor: RpcMessageCursorPayload, snapshot: RpcMessageSnapshot): boolean {
return (
cursor.sessionId === snapshot.sessionId &&
cursor.leafId === snapshot.leafId &&
cursor.messageCount === snapshot.messageCount
);
}
/** Page one stable in-memory message snapshot without crossing the v1 frame budget. */
export function pageRpcMessages(
messages: readonly AgentMessage[],
snapshot: RpcMessageSnapshot,
options: RpcMessagesPageOptions = {},
): RpcMessagesPage {
if (snapshot.messageCount !== messages.length)
throw new Error("RPC message snapshot does not match current messages");
const limit = options.limit ?? DEFAULT_RPC_MESSAGE_PAGE_LIMIT;
if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_RPC_MESSAGE_PAGE_LIMIT)
throw new Error(`RPC message page limit must be between 1 and ${MAX_RPC_MESSAGE_PAGE_LIMIT}`);
let offset = 0;
if (options.cursor !== undefined) {
const cursor = decodeCursor(options.cursor);
if (!sameSnapshot(cursor, snapshot))
throw new RpcMessagesPageError(RPC_MESSAGES_PAGE_STALE_ERROR, "stale_cursor");
offset = cursor.offset;
}
const page: AgentMessage[] = [];
let pageBytes = 2;
while (offset + page.length < messages.length && page.length < limit) {
const message = messages[offset + page.length];
const messageBytes = Buffer.byteLength(JSON.stringify(message), "utf8") + (page.length === 0 ? 0 : 1);
if (page.length > 0 && pageBytes + messageBytes > MAX_RPC_MESSAGE_PAGE_BYTES) break;
page.push(message);
pageBytes += messageBytes;
}
View on GitHub (pinned to 9690622007)
Solutions
- Clamp limit before calling: Math.min(Math.max(1, Math.floor(limit)), 256), or omit it to use the default 100.
- Convert string inputs to numbers first and reject NaN: const n = Number(raw); if (!Number.isSafeInteger(n)) omit or default.
- Use limit ≤ 256 and iterate pages with nextCursor instead of trying to fetch everything in one request.
- Guard UI/state code so limit can never become 0 or negative when computing page sizes.
Example fix
// before
const limit = Number(query.get('limit')); // NaN when absent
page(messages, snapshot, { limit });
// after
const raw = Number(query.get('limit'));
const limit = Number.isSafeInteger(raw) ? Math.min(Math.max(1, raw), 256) : undefined;
page(messages, snapshot, limit ? { limit } : {}); Defensive patterns
Strategy: validation
Validate before calling
function clampLimit(raw: unknown): number | undefined {
const n = typeof raw === "string" ? Number(raw) : raw;
return typeof n === "number" && Number.isSafeInteger(n) && n >= 1 && n <= 256 ? n : undefined;
} Type guard
function isValidPageLimit(v: unknown): v is number {
return typeof v === "number" && Number.isSafeInteger(v) && v >= 1 && v <= 256;
} Try / catch
try {
return page(messages, snapshot, { limit });
} catch (err) {
if (String(err.message).startsWith("RPC message page limit")) {
return page(messages, snapshot, {}); // fall back to default limit 100
}
throw err;
} Prevention
- Clamp user-supplied limits into [1, 256] before calling
- Coerce string query params with Number() and verify Number.isSafeInteger
- Page with nextCursor instead of requesting oversized limits
When it happens
Trigger: Calling pageRpcMessages / get_messages_page with limit: 0, limit: -1, limit: 1000, limit: 12.5, or limit: NaN; forwarding an unvalidated user-supplied query parameter as limit.
Common situations: Clients implementing 'fetch all' by passing a huge limit; parsing limit from a URL/string without Number() conversion ('20' as string fails Number.isSafeInteger? — actually strings fail the check); tests probing bounds; UI pagination math producing 0.
Related errors
- Invalid RPC message cursor
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
- Invalid pattern: {err}
- Invalid package name: ${name}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5c368ddcd81b60ee.
Report an issue: GitHub.