mastra-ai/mastra · error

CursorSDKAgent resumeData.agentId must be a string when prov

Error message

CursorSDKAgent resumeData.agentId must be a string when provided.

What it means

validateCursorResumeData permits an optional agentId but enforces its type: if resumeData.agentId is present it must be a string. Any other type (number, object, etc.) triggers this error.

Source

Thrown at agent-sdks/cursor/src/index.ts:294

  private async resolveResumeCursorAgent(resumeData: CursorSDKAgentResumeData): Promise<SDKAgent> {
    if (!resumeData.agentId) {
      return this.resolveCursorAgent();
    }

    return CursorAgent.resume(resumeData.agentId, {
      ...toCursorCreateOptions(this.options),
      ...resumeData.sdkOptions,
    });
  }
}

function validateCursorResumeData(resumeData: CursorSDKAgentResumeData): CursorSDKAgentResumeData {
  if (!toRecord(resumeData) || !('message' in resumeData)) {
    throw new Error('CursorSDKAgent resumeData must include a message.');
  }

  if (resumeData.agentId !== undefined && typeof resumeData.agentId !== 'string') {
    throw new Error('CursorSDKAgent resumeData.agentId must be a string when provided.');
  }

  return resumeData;
}

function assertStructuredOutputUnsupported(options?: unknown): void {
  const structuredOutput = toRecord(toRecord(options)?.structuredOutput);
  if (structuredOutput && 'schema' in structuredOutput) {
    throw new Error(
      'CursorSDKAgent does not support structuredOutput because the Cursor TypeScript SDK does not expose a schema-constrained output API.',
    );
  }
}

async function runCursorGenerate(
  prompt: string,
  options: CursorAgentOptions,
  agent: SDKAgent,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Convert the agentId to a string before resuming: String(saved.agentId).
  2. Omit the agentId field entirely if you don't have a valid one.
  3. Validate typeof resumeData.agentId === 'string' || resumeData.agentId === undefined before calling resume.

Example fix

// before
await agent.resume({ message, agentId: 12345 });
// after
await agent.resume({ message, agentId: String(12345) });
Defensive patterns

Strategy: type-guard

Validate before calling

if (saved.agentId !== undefined && typeof saved.agentId !== 'string') {
  saved.agentId = String(saved.agentId);
}
await agent.resume(saved);

Type guard

function hasStringAgentId(v: unknown): v is { message: unknown; agentId?: string } {
  const d = v as { agentId?: unknown };
  return d.agentId === undefined || typeof d.agentId === 'string';
}

Try / catch

try {
  await agent.resume(saved);
} catch (e) {
  if (e instanceof Error && e.message.includes('agentId must be a string')) {
    await agent.resume({ ...saved, agentId: String(saved.agentId) });
  } else throw e;
}

Prevention

When it happens

Trigger: cursorSDKAgent.resume({ message, agentId: 12345 }) — passing a numeric or otherwise non-string agentId, often from JSON parsing quirks or copying an ID from a numeric database column.

Common situations: Storing Cursor agent IDs as numbers in a DB and passing them through unconverted; loosely typed configs; deserialization changing the ID type.

Related errors


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