mastra-ai/mastra · error
Invalid MemoryRequestContext.thread.id: expected string, got
Error message
Invalid MemoryRequestContext.thread.id: expected string, got ${typeof thread.id} What it means
parseMemoryRequestContext reads the 'MastraMemory' entry from the RequestContext and validates its shape before memory features use it. This error is thrown when a thread object is provided in the memory request context but its `id` property is not a string. The library throws it because all downstream memory operations (thread lookup, message persistence) depend on a string thread id.
Source
Thrown at packages/core/src/memory/types.ts:163
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[];
}[T];
type BaseWorkingMemory = {
enabled: boolean;View on GitHub (pinned to 75dd419e61)
Solutions
- Ensure the object stored under the 'MastraMemory' RequestContext key has `thread.id` set to a non-empty string before the request runs.
- Stringify numeric/other ids at construction: `thread: { id: String(row.id) }`.
- If thread is optional, omit the whole `thread` key (set undefined) rather than passing a partial object without an id.
- Call parseMemoryRequestContext yourself (or a typeof check) when constructing custom RequestContext entries to fail early with a clearer stack.
Example fix
// before
requestContext.set('MastraMemory', { thread: { id: 42 }, resourceId: 'user-1' });
// after
requestContext.set('MastraMemory', { thread: { id: '42' }, resourceId: 'user-1' }); Defensive patterns
Strategy: type-guard
Validate before calling
const ctx = requestContext?.get('MastraMemory');
if (ctx && ctx.thread != null && typeof ctx.thread.id !== 'string') {
throw new TypeError(`thread.id must be a string, got ${typeof ctx.thread.id}`);
} Type guard
function hasStringThreadId(ctx: unknown): ctx is { thread: { id: string } } {
return typeof ctx === 'object' && ctx !== null &&
'thread' in ctx && typeof (ctx as any).thread?.id === 'string';
} Try / catch
try {
const memCtx = parseMemoryRequestContext(requestContext);
// use memCtx
} catch (err) {
if (err instanceof Error && err.message.includes('thread.id')) {
logger.error('Malformed memory context: thread.id is not a string', { err });
return; // skip memory for this request or fix context upstream
}
throw err;
} Prevention
- Always construct thread ids with String(...) at the boundary where ids originate.
- Set the 'MastraMemory' RequestContext entry only through helper APIs, not by hand.
- Add a runtime schema check (zod) on context objects before storing them.
- Never store partial thread objects; omit the key when there is no thread.
When it happens
Trigger: Calling any memory-consuming API (memoryContext, threadId, memoryRunState, getThreadId, resolveThreadId, memoryConfig) with a RequestContext whose 'MastraMemory' entry contains `thread` as an object whose `id` is not a string — e.g. `thread: { id: 123 }`, `{ id: undefined }`, `{ id: null }`, `{ }`, or a thread object deserialized from JSON where id became a number.
Common situations: Passing a numeric database primary key as thread id instead of stringifying it; building the context manually instead of via the memory helper APIs; serializing/deserializing context over HTTP where id type drifts; copying a thread object from a different ORM where id is a number or ObjectId.
Related errors
- Invalid MemoryRequestContext: expected object, got ${typeof
- Invalid MemoryRequestContext.thread: expected object, got ${
- Invalid MemoryRequestContext.resourceId: expected string, go
- MastraClient.deleteThread() requires exactly one of agentId
- ${label} must be a string.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/2def34bb7c18645d.
Report an issue: GitHub.