Bug Description
The API loader endpoint for retrieving run events queries all events matching the trace of a run and sends them back in a single unpaginated JSON array:
const runEvents = await eventRepository.getRunEvents(
getTaskEventStoreTableForRun(run),
authentication.environment.id,
run.traceId,
run.friendlyId,
run.createdAt,
run.completedAt ?? undefined
);
return json(
{
events: runEvents.map((event) => {
return JSON.parse(
JSON.stringify(event, (_, value) =>
typeof value === "bigint" ? value.toString() : value
)
);
}),
},
{ status: 200 }
);
Complex, nested workflows or large loops can easily spawn thousands of trace spans and event logs. Querying, mapping, stringifying, and parsing the entire trace set in memory on a single request exposes the webapp process to heap exhaustion and Out of Memory (OOM) crashes.
Root Cause File
apps/webapp/app/routes/api.v1.runs.$runId.events.ts
Proposed Fix
Support standard offset or cursor-based pagination parameters (limit, cursor, offset) on the /api/v1/runs/:runId/events endpoint, enforcing a maximum batch size per query.
Bug Description
The API loader endpoint for retrieving run events queries all events matching the trace of a run and sends them back in a single unpaginated JSON array:
Complex, nested workflows or large loops can easily spawn thousands of trace spans and event logs. Querying, mapping, stringifying, and parsing the entire trace set in memory on a single request exposes the webapp process to heap exhaustion and Out of Memory (OOM) crashes.
Root Cause File
apps/webapp/app/routes/api.v1.runs.$runId.events.tsProposed Fix
Support standard offset or cursor-based pagination parameters (
limit,cursor,offset) on the/api/v1/runs/:runId/eventsendpoint, enforcing a maximum batch size per query.