mastra-ai/mastra · error

runId is required when resumeData is provided

Error message

runId is required when resumeData is provided

What it means

The AI SDK chat route handler accepts resumeData to resume a previously interrupted agent run. Resuming requires identifying which run to resume, supplied via runId. Providing resumeData without runId is ambiguous and rejected at the start of handleChatStream before any agent lookup.

Source

Thrown at client-sdks/ai-sdk/src/chat-route.ts:298

  agentId,
  agentVersion,
  params,
  defaultOptions,
  experimentalTransform,
  version = 'v5',
  sendStart = true,
  sendFinish = true,
  sendReasoning = false,
  sendSources = false,
  onError,
  messageMetadata,
}: Omit<ChatStreamHandlerOptions<any, OUTPUT>, 'messageMetadata'> & {
  messageMetadata?: any;
}): Promise<ReadableStream<any>> {
  const { messages, resumeData, runId, requestContext, trigger, ...rest } = params;

  if (resumeData && !runId) {
    throw new Error('runId is required when resumeData is provided');
  }

  const baseAgent = mastra.getAgentById(agentId);
  if (!baseAgent) {
    throw new Error(`Agent ${agentId} not found`);
  }

  // When an editor is configured, an agent's runtime config (instructions, tools,
  // model, ...) can live in stored config rather than the code definition. Studio
  // resolves these stored overrides before every run, so this endpoint must do the
  // same or it would execute a stale/empty code-defined agent (issue #18574). An
  // explicit agentVersion (from query params or route options) wins; otherwise we
  // default to the published version, matching the built-in agent handlers.
  let agentObj = baseAgent;
  const editorAgent = mastra.getEditor?.()?.agent;
  if (editorAgent) {
    agentObj = await editorAgent.applyStoredOverrides(
      baseAgent,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Include the runId field in the request body alongside resumeData
  2. On the client, persist both runId and resumeData together when a stream is interrupted, and send both when resuming
  3. If the request is not meant to resume, remove resumeData from the payload
  4. Update the client SDK version so resume helpers include runId automatically

Example fix

// before
resumeChat({ resumeData: saved.resumeData })
// after
resumeChat({ runId: saved.runId, resumeData: saved.resumeData })
Defensive patterns

Strategy: validation

Validate before calling

if (body.resumeData && !body.runId) {
  throw new Error('runId must accompany resumeData');
}

Type guard

function canResume(b: { resumeData?: unknown; runId?: string }): b is { resumeData: unknown; runId: string } {
  return b.resumeData === undefined || typeof b.runId === 'string' && b.runId.length > 0;
}

Try / catch

try {
  const stream = await handleChatStream({ ...params, resumeData, runId });
} catch (err) {
  if (err instanceof Error && err.message.includes('runId is required')) {
    // fall back to starting a fresh run without resumeData
  }
}

Prevention

When it happens

Trigger: POSTing to the chat route with a body containing resumeData but omitting runId; frontend resume logic that sends the saved resume payload from storage but loses the runId field.

Common situations: Custom resume UIs that persisted resumeData but not runId; older clients predating the runId requirement; manual curl/testing payloads that include partial resume state.

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/8313bfdb985a9ae2. Report an issue: GitHub.