mastra-ai/mastra · error · MastraError
AGENT_LIST_SUSPENDED_RUNS_INVALID_PER_PAGE
AGENT_LIST_SUSPENDED_RUNS_INVALID_PER_PAGE
Error message
Agent "${this.name}" listSuspendedRuns() requires perPage to be a positive integer. What it means
agent.listSuspendedRuns() validates its pagination options before querying storage. If perPage is provided but is not a positive integer (non-integer, zero, or negative), Mastra throws AGENT_LIST_SUSPENDED_RUNS_INVALID_PER_PAGE immediately with the agent name and offending value in details.
Source
Thrown at packages/core/src/agent/agent.ts:8120
* `approveToolCall()`, or `declineToolCall()`.
*
* Results are scoped to runs started by this agent: snapshots persist the owning
* agent's id, and runs whose snapshots carry a different id are skipped. Filter by
* `threadId`/`resourceId` to scope results to a conversation.
*
* @example
* ```typescript
* const { runs } = await agent.listSuspendedRuns({ threadId, resourceId });
* if (runs[0]) {
* await agent.approveToolCall({ runId: runs[0].runId });
* }
* ```
*/
async listSuspendedRuns(options: AgentListSuspendedRunsOptions = {}): Promise<AgentListSuspendedRunsResult> {
const { threadId, resourceId, fromDate, toDate, perPage, page } = options;
if (perPage !== undefined && (!Number.isInteger(perPage) || perPage <= 0)) {
throw new MastraError({
id: 'AGENT_LIST_SUSPENDED_RUNS_INVALID_PER_PAGE',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
text: `Agent "${this.name}" listSuspendedRuns() requires perPage to be a positive integer.`,
details: { agentName: this.name, perPage },
});
}
if (page !== undefined && (!Number.isInteger(page) || page < 0)) {
throw new MastraError({
id: 'AGENT_LIST_SUSPENDED_RUNS_INVALID_PAGE',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
text: `Agent "${this.name}" listSuspendedRuns() requires page to be a non-negative integer.`,
details: { agentName: this.name, page },
});
}
const effectiveMastra = this.#mastra ?? (await this.#getOrCreateEphemeralMastra());View on GitHub (pinned to 75dd419e61)
Solutions
- Pass a positive integer (>= 1) for perPage, or omit it to use the default.
- Coerce and validate user-supplied values before calling: Number.isInteger(v) && v > 0.
- If you intended 'no limit', drop perPage rather than passing 0.
Example fix
// before
await agent.listSuspendedRuns({ perPage: Number(searchParams.get('perPage')) });
// after
const perPage = Number(searchParams.get('perPage'));
await agent.listSuspendedRuns(perPage > 0 && Number.isInteger(perPage) ? { perPage } : {}); Defensive patterns
Strategy: validation
Validate before calling
function isValidPerPage(v: unknown): v is number {
return typeof v === 'number' && Number.isInteger(v) && v > 0;
}
const opts = isValidPerPage(rawPerPage) ? { perPage: rawPerPage } : {}; Type guard
function isPositiveInt(v: unknown): v is number {
return Number.isInteger(v) && (v as number) > 0;
} Try / catch
try {
await agent.listSuspendedRuns({ perPage });
} catch (e) {
if (e instanceof MastraError && e.id === 'AGENT_LIST_SUSPENDED_RUNS_INVALID_PER_PAGE') {
return agent.listSuspendedRuns(); // fall back to defaults
}
throw e;
} Prevention
- Coerce and clamp query-string params before passing pagination options.
- Use zod or similar to validate options objects at API boundaries.
- Treat 'all results' as omitting perPage, not perPage: 0.
When it happens
Trigger: Calling agent.listSuspendedRuns({ perPage: 0 }) or perPage: -10, perPage: 2.5, or perPage: NaN (e.g. derived from parsed query params without validation).
Common situations: Passing URL query string values parsed as strings or floats into perPage; computing page size from user input; defaulting with 0 to mean 'no limit'.
Related errors
- AGENT_LIST_SUSPENDED_RUNS_INVALID_PAGE
- GitHub cursor must be a positive page number.
- GitHub cursor must be a positive page number.
- AGENT_REQUEST_CONTEXT_VALIDATION_FAILED
- Either message or messages must be provided
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b8dff0a736f99240.
Report an issue: GitHub.