mastra-ai/mastra · error
Invalid MemoryRequestContext.thread: expected object, got ${
Error message
Invalid MemoryRequestContext.thread: expected object, got ${typeof ctx.thread} What it means
parseMemoryRequestContext validates that ctx.thread, when present, is an object with a string id. If ctx.thread exists but is not an object (e.g. a string or number), this error is thrown. It is a distinct check from error 1443: the top-level context is a valid object, but its 'thread' field has the wrong type.
Source
Thrown at packages/core/src/memory/types.ts:159
return null;
}
const memoryContext = requestContext.get('MastraMemory');
if (!memoryContext) {
return null;
}
// Validate the structure
if (typeof memoryContext !== 'object' || memoryContext === null) {
throw new Error(`Invalid MemoryRequestContext: expected object, got ${typeof memoryContext}`);
}
const ctx = memoryContext as Record<string, unknown>;
// Validate thread if present
if (ctx.thread !== undefined) {
if (typeof ctx.thread !== 'object' || ctx.thread === null) {
throw new Error(`Invalid MemoryRequestContext.thread: expected object, got ${typeof ctx.thread}`);
}
const thread = ctx.thread as Record<string, unknown>;
if (typeof thread.id !== 'string') {
throw new Error(`Invalid MemoryRequestContext.thread.id: expected string, got ${typeof thread.id}`);
}
}
// Validate resourceId if present
if (ctx.resourceId !== undefined && typeof ctx.resourceId !== 'string') {
throw new Error(`Invalid MemoryRequestContext.resourceId: expected string, got ${typeof ctx.resourceId}`);
}
return memoryContext as MemoryRequestContext;
}
export type MessageResponse<T extends 'raw' | 'core_message'> = {
raw: MastraMessageV1[];
core_message: CoreMessage[];View on GitHub (pinned to 75dd419e61)
Solutions
- Wrap the thread ID in an object: { thread: { id: 'thread-123' } }
- If you only have a thread ID, use the threadId field of the request context instead of nesting a string under thread
- Fix payload construction upstream (server proxy, SDK version mismatch) so thread arrives as an object
- Validate with the type guard below before assigning to memoryContext
Example fix
// before
memoryContext: { thread: 'thread-123' }
// after
memoryContext: { thread: { id: 'thread-123' } } Defensive patterns
Strategy: type-guard
Validate before calling
function isValidThreadField(t: unknown): boolean {
return t === undefined || (typeof t === 'object' && t !== null && typeof (t as { id?: unknown }).id === 'string');
}
// before assigning:
if (!isValidThreadField(rawContext?.thread)) throw new TypeError('thread must be an object with string id'); Type guard
function isThreadRef(v: unknown): v is { id: string } {
return typeof v === 'object' && v !== null && typeof (v as { id?: unknown }).id === 'string';
} Try / catch
try {
const ctx = parseMemoryRequestContext(memoryContext);
} catch (err) {
if (err instanceof Error && err.message.includes('.thread:')) {
// normalize legacy bare-string thread IDs
if (typeof (memoryContext as { thread?: unknown })?.thread === 'string') {
memoryContext = { ...memoryContext, thread: { id: (memoryContext as { thread: string }).thread } };
return parseMemoryRequestContext(memoryContext);
}
throw new TypeError('memoryContext.thread must be { id: string }');
}
throw err;
} Prevention
- Always nest thread IDs as { thread: { id } }, never as a raw string
- Distinguish the thread object field from the flat threadId field and use each consistently
- Type request builders with the MemoryRequestContext type to catch wrong nesting at compile time
- Normalize legacy payloads (bare thread ID strings) at your API edge before passing to Mastra
- Add a unit test that round-trips your context serialization to ensure the thread field shape survives
When it happens
Trigger: Passing { thread: 'thread-123' } or { thread: 42 } instead of { thread: { id: 'thread-123' } } in memory request context; also a null thread field reaches this branch since it is neither undefined nor an object.
Common situations: Migrating from APIs that accepted a bare thread ID string in the thread field; hand-built request payloads in tests; backend proxies reshaping payloads incorrectly; confusion between thread (object) and threadId (string) field names across Mastra versions.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid MemoryRequestContext: expected object, got ${typeof
- Invalid MemoryRequestContext.thread.id: expected string, got
- Invalid MemoryRequestContext.resourceId: expected string, go
- CursorSDKAgent resumeData.agentId must be a string when prov
- MastraClient.deleteThread() requires exactly one of agentId
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/09208a68b9e17102.
Report an issue: GitHub.