mastra-ai/mastra · error · HTTPException
runId required to time travel workflow
Error message
runId required to time travel workflow
What it means
POST /workflows/:workflowId/time-travel-async returns 400 with this message when the runId query parameter is missing. Time travel always operates on an existing run, so the handler rejects requests without runId before doing any lookup.
Source
Thrown at packages/server/src/server/handlers/workflows.ts:1157
responseType: 'json',
pathParamSchema: workflowIdPathParams,
queryParamSchema: runIdSchema,
bodySchema: timeTravelBodySchema,
responseSchema: workflowExecutionResultSchema,
summary: 'Time travel workflow asynchronously',
description: 'Time travels a workflow run asynchronously without streaming',
tags: ['Workflows'],
requiresAuth: true,
handler: async ({ mastra, workflowId, runId, requestContext, ...params }) => {
try {
const effectiveResourceId = getEffectiveResourceId(requestContext, undefined);
if (!workflowId) {
throw new HTTPException(400, { message: 'Workflow ID is required' });
}
if (!runId) {
throw new HTTPException(400, { message: 'runId required to time travel workflow' });
}
const { workflow } = await listWorkflowsFromSystem({ mastra, workflowId });
if (!workflow) {
throw new HTTPException(404, { message: 'Workflow not found' });
}
const run = await workflow.getWorkflowRunById(runId);
if (!run) {
throw new HTTPException(404, { message: 'Workflow run not found' });
}
await validateRunOwnership(run, effectiveResourceId);
const _run = await workflow.createRun({ runId, resourceId: run.resourceId });
const result = await _run.timeTravel({ ...params, requestContext });View on GitHub (pinned to 75dd419e61)
Solutions
- Append ?runId=<runId> to the request URL
- Verify the runId value is defined and non-empty before issuing the request
- Use the run id returned by workflow.createRun() or from the stored run, not the workflow id
Example fix
// before
await fetch(`/api/workflows/${workflowId}/time-travel-async`, { method: 'POST', body });
// after
await fetch(`/api/workflows/${workflowId}/time-travel-async?runId=${runId}`, { method: 'POST', body }); Defensive patterns
Strategy: validation
Validate before calling
if (!runId) throw new Error('runId is required');
const url = `/api/workflows/${workflowId}/time-travel-async?runId=${encodeURIComponent(runId)}`; Type guard
function hasRunId(v: unknown): v is string {
return typeof v === 'string' && v.length > 0;
} Try / catch
try {
return await timeTravelAsync(workflowId, runId);
} catch (e) {
if (isHttpError(e) && e.status === 400 && /runId required/.test(e.message)) {
console.error('Missing runId query param:', { workflowId, runId });
}
throw e;
} Prevention
- Always pass runId as a query param, not in the body, for time-travel routes
- Capture the run id returned by createRun() and persist it
- Validate runId is non-empty before constructing the URL
When it happens
Trigger: POST /workflows/:workflowId/time-travel-async without the ?runId= query param (runIdSchema query param absent, null, or empty string).
Common situations: Forgetting the query param while testing with curl/Postman; client code passes runId in the body instead of the query string; runId variable undefined at call time.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Agent ID is required
- Could not derive scorer definition ID from name. Please prov
- Argument "${key}" is required
- Invalid request index, indexName and positive dimension numb
- Invalid metric. Must be one of: cosine, euclidean, dotproduc
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/09ae381f7fba9e57.
Report an issue: GitHub.