Bug
inputToMastraDBMessage() throws Received input message with wrong threadId when an agent is called with memory that uses resource-scoped observational memory and the user has messages on multiple threads.
Reproduction
- Configure memory with
observationalMemory: { scope: "resource" } and lastMessages: 5
- Create messages on thread A for a resource (e.g. a chat thread)
- Call
agent.generate() with memory: { thread: "thread-B", resource: "same-resource" }
- Wait for the user to accumulate enough messages for observational memory to trigger (30k+ tokens)
- On the next agent call,
getContext() calls listMessagesByResourceId() which fetches messages from ALL threads (A and B)
- Messages from thread A have
threadId: "thread-A" but the agent expects threadId: "thread-B"
inputToMastraDBMessage() throws because messageSource !== "memory" and threadIds don't match
Root Cause
In @mastra/memory, getContext() at index.js:17362-17369 uses listMessagesByResourceId() when omEngine.scope === "resource" — this returns messages from all threads. But inputToMastraDBMessage() in @mastra/core at input-converter.ts validates that every non-memory message's threadId matches the agent's target thread. The retrieval and validation are incompatible.
Expected Behavior
Cross-thread messages retrieved by getContext() should either:
- Be tagged with
messageSource: "memory" so they bypass the validation
- Have their
threadId reassigned to the target thread
- Or the validation should be scoped to only user-provided input messages, not internally-retrieved ones
Versions
@mastra/core: 1.23.0, 1.24.1 (confirmed present in both)
@mastra/memory: 1.14.0, 1.15.0
Workaround
We patched inputToMastraDBMessage() to reassign message.threadId = context.memoryInfo.threadId instead of throwing.
Bug
inputToMastraDBMessage()throwsReceived input message with wrong threadIdwhen an agent is called with memory that uses resource-scoped observational memory and the user has messages on multiple threads.Reproduction
observationalMemory: { scope: "resource" }andlastMessages: 5agent.generate()withmemory: { thread: "thread-B", resource: "same-resource" }getContext()callslistMessagesByResourceId()which fetches messages from ALL threads (A and B)threadId: "thread-A"but the agent expectsthreadId: "thread-B"inputToMastraDBMessage()throws becausemessageSource !== "memory"and threadIds don't matchRoot Cause
In
@mastra/memory,getContext()at index.js:17362-17369 useslistMessagesByResourceId()whenomEngine.scope === "resource"— this returns messages from all threads. ButinputToMastraDBMessage()in@mastra/coreat input-converter.ts validates that every non-memory message'sthreadIdmatches the agent's target thread. The retrieval and validation are incompatible.Expected Behavior
Cross-thread messages retrieved by
getContext()should either:messageSource: "memory"so they bypass the validationthreadIdreassigned to the target threadVersions
@mastra/core: 1.23.0, 1.24.1 (confirmed present in both)@mastra/memory: 1.14.0, 1.15.0Workaround
We patched
inputToMastraDBMessage()to reassignmessage.threadId = context.memoryInfo.threadIdinstead of throwing.