mastra-ai/mastra · error

OpenAISDKAgent resumeData must include a message.

Error message

OpenAISDKAgent resumeData must include a message.

What it means

validateOpenAIResumeData requires resumeData to be an object containing a 'message' property — the conversation message used to resume an OpenAI Agents SDK session. It throws when resumeData is not a record or lacks the message key.

Source

Thrown at agent-sdks/openai/src/index.ts:246

    return this.stream(data.message, createOpenAIResumeRunOptions(data, options));
  }

  private resolveOpenAIAgent(): OpenAIAgent {
    this.#createdAgent ??= this.options.agent ?? new OpenAIAgent(toOpenAIAgentOptions(this.options));
    return this.#createdAgent;
  }
}

function getStructuredOutputOption<OUTPUT>(
  options?: SDKAgentRunOptions<OUTPUT>,
): OpenAIStructuredOutputOption<OUTPUT> | undefined {
  return options?.structuredOutput as OpenAIStructuredOutputOption<OUTPUT> | undefined;
}

function validateOpenAIResumeData(resumeData: OpenAISDKAgentResumeData): OpenAISDKAgentResumeData {
  const record = toRecord(resumeData);
  if (!record || !('message' in record)) {
    throw new Error('OpenAISDKAgent resumeData must include a message.');
  }

  if (
    typeof resumeData.previousResponseId === 'string' ||
    typeof resumeData.conversationId === 'string' ||
    resumeData.session !== undefined
  ) {
    return resumeData;
  }

  throw new Error('OpenAISDKAgent resumeData must include previousResponseId, conversationId, or session.');
}

function createOpenAIResumeRunOptions<OUTPUT>(
  resumeData: OpenAISDKAgentResumeData,
  options?: SDKAgentRunOptions<OUTPUT>,
): SDKAgentRunOptions<OUTPUT> {
  return {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Include the prior conversation message: resume({ message: savedMessage }).
  2. Persist the complete OpenAISDKAgentResumeData (message plus any previousResponseId/conversationId/session) instead of just identifiers.
  3. Validate before calling: object check plus 'message' in resumeData.

Example fix

// before
await agent.resume({ previousResponseId: saved.responseId });
// after
await agent.resume({ message: saved.message, previousResponseId: saved.responseId });
Defensive patterns

Strategy: validation

Validate before calling

function canResumeOpenAI(data: unknown): boolean {
  return typeof data === 'object' && data !== null && 'message' in data;
}
if (!canResumeOpenAI(saved)) throw new Error('Saved OpenAI resume data is missing message');
await agent.resume(saved);

Type guard

function isOpenAIResumeData(v: unknown): v is OpenAISDKAgentResumeData {
  return typeof v === 'object' && v !== null && 'message' in v;
}

Try / catch

try {
  await agent.resume(saved);
} catch (e) {
  if (e instanceof Error && e.message.includes('resumeData must include a message')) {
    // fall back to a fresh generate
    await agent.generate(prompt);
  } else throw e;
}

Prevention

When it happens

Trigger: openAISDKAgent.resume(data) with an empty object, a non-object value, or an object containing only previousResponseId/conversationId/session but no message.

Common situations: Persisting only the OpenAI response/conversation ID and attempting to resume with it alone; reusing resume data shaped for the Claude or Cursor SDK agents; hand-building resumeData after deserialization drops fields.

Related errors


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