mastra-ai/mastra · error · HTTPException
Invalid createdAt
Error message
Invalid createdAt
What it means
Thrown with HTTP 400 when an incoming workflow event's `createdAt` cannot be parsed into a valid Date. The route coerces the wire-format string timestamp to a Date before handing the event to `mastra.handleWorkflowEvent`; an unparsable value means the payload's timestamp field is malformed.
Source
Thrown at packages/server/src/server/handlers/workflows.ts:1616
bodySchema: receiveWorkflowEventBodySchema,
responseSchema: receiveWorkflowEventResponseSchema,
summary: 'Receive a workflow event from a push-mode broker',
description:
'Push-mode entry point for workflow events. Brokers (GCP Pub/Sub push, SNS, EventBridge) POST each event here; Mastra processes it through the same pipeline as pull-mode workers.',
tags: ['Workflows', 'Worker'],
requiresAuth: true,
// Broker push endpoint: it advances runtime state rather than editing
// definitions, so `workflows:execute` is the more accurate fit. `write` is
// kept for back-compat with service principals that already grant it.
requiresPermission: ['workflows:write', 'workflows:execute'],
handler: (async ({ mastra, event }: ReceiveWorkflowEventHandlerArgs) => {
try {
// The wire schema carries `createdAt` as a string; coerce to Date here
// before handing off to the in-process pipeline, which expects an `Event`.
const rawCreatedAt = (event as unknown as { createdAt: unknown }).createdAt;
const createdAt = rawCreatedAt instanceof Date ? rawCreatedAt : new Date(rawCreatedAt as string);
if (Number.isNaN(createdAt.getTime())) {
throw new HTTPException(400, { message: 'Invalid createdAt' });
}
return await mastra.handleWorkflowEvent({ ...event, createdAt });
} catch (error) {
return handleError(error, 'Error receiving workflow event');
}
}) as any,
});
View on GitHub (pinned to 75dd419e61)
Solutions
- Send `createdAt` as an ISO 8601 string (e.g. new Date().toISOString())
- Send a Date-serializable value or omit the field only if your version allows it
- Validate the timestamp parses before POSTing the event
Example fix
// before
body: { ...event, createdAt: String(Date.now()) }
// after
body: { ...event, createdAt: new Date().toISOString() } Defensive patterns
Strategy: validation
Validate before calling
const d = new Date(event.createdAt); if (Number.isNaN(d.getTime())) throw new Error(`Invalid createdAt: ${event.createdAt}`); Type guard
const isValidDateInput = (v: unknown): v is string | Date => typeof v === 'string' ? !Number.isNaN(new Date(v).getTime()) : v instanceof Date && !Number.isNaN(v.getTime());
Try / catch
try { await postWorkflowEvent(event); } catch (e) { if (isHttpException(e, 400) && /createdAt/.test(e.message)) console.error('Fix event.createdAt to ISO 8601', event.createdAt); else throw e; } Prevention
- Always serialize timestamps with toISOString()
- Unit-test event payloads for schema compliance
- Avoid locale-specific date formatting in producers
When it happens
Trigger: POSTing a workflow event whose `createdAt` is undefined, an empty string, or a non-ISO string that `new Date(...)` cannot parse; producers emitting epoch numbers or locale-formatted dates.
Common situations: Custom producers emitting timestamps without toISOString(); forgetting to set createdAt when forwarding events; time libraries serializing with non-ISO formats.
Related errors
- bad request: ${responseText}
- Invalid notification dispatch time: ${input}
- Invalid Subconscious record time: ${value}
- Invalid agent-builder action: ${actionId}. Valid actions are
- Invalid agent-builder action: ${actionId}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/8974fa212e409e6a.
Report an issue: GitHub.