{"record":{"id":"2def34bb7c18645d","repo":"mastra-ai/mastra","slug":"invalid-memoryrequestcontext-thread-id-expected-s","errorCode":null,"errorMessage":"Invalid MemoryRequestContext.thread.id: expected string, got ${typeof thread.id}","messagePattern":"Invalid MemoryRequestContext\\.thread\\.id: expected string, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/memory/types.ts","lineNumber":163,"sourceCode":"  if (!memoryContext) {\n    return null;\n  }\n\n  // Validate the structure\n  if (typeof memoryContext !== 'object' || memoryContext === null) {\n    throw new Error(`Invalid MemoryRequestContext: expected object, got ${typeof memoryContext}`);\n  }\n\n  const ctx = memoryContext as Record<string, unknown>;\n\n  // Validate thread if present\n  if (ctx.thread !== undefined) {\n    if (typeof ctx.thread !== 'object' || ctx.thread === null) {\n      throw new Error(`Invalid MemoryRequestContext.thread: expected object, got ${typeof ctx.thread}`);\n    }\n    const thread = ctx.thread as Record<string, unknown>;\n    if (typeof thread.id !== 'string') {\n      throw new Error(`Invalid MemoryRequestContext.thread.id: expected string, got ${typeof thread.id}`);\n    }\n  }\n\n  // Validate resourceId if present\n  if (ctx.resourceId !== undefined && typeof ctx.resourceId !== 'string') {\n    throw new Error(`Invalid MemoryRequestContext.resourceId: expected string, got ${typeof ctx.resourceId}`);\n  }\n\n  return memoryContext as MemoryRequestContext;\n}\n\nexport type MessageResponse<T extends 'raw' | 'core_message'> = {\n  raw: MastraMessageV1[];\n  core_message: CoreMessage[];\n}[T];\n\ntype BaseWorkingMemory = {\n  enabled: boolean;","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/memory/types.ts#L145-L181","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nrequestContext.set('MastraMemory', { thread: { id: 42 }, resourceId: 'user-1' });\n// after\nrequestContext.set('MastraMemory', { thread: { id: '42' }, resourceId: 'user-1' });","handlingStrategy":"type-guard","validationCode":"const ctx = requestContext?.get('MastraMemory');\nif (ctx && ctx.thread != null && typeof ctx.thread.id !== 'string') {\n  throw new TypeError(`thread.id must be a string, got ${typeof ctx.thread.id}`);\n}","typeGuard":"function hasStringThreadId(ctx: unknown): ctx is { thread: { id: string } } {\n  return typeof ctx === 'object' && ctx !== null &&\n    'thread' in ctx && typeof (ctx as any).thread?.id === 'string';\n}","tryCatchPattern":"try {\n  const memCtx = parseMemoryRequestContext(requestContext);\n  // use memCtx\n} catch (err) {\n  if (err instanceof Error && err.message.includes('thread.id')) {\n    logger.error('Malformed memory context: thread.id is not a string', { err });\n    return; // skip memory for this request or fix context upstream\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["memory","validation","request-context","typescript"],"backgroundTag":"invalid-memory-request-context","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}