{"record":{"id":"bdd39fe1fc0d4efa","repo":"mastra-ai/mastra","slug":"resource-scoped-message-listing-is-not-implemented","errorCode":null,"errorMessage":"Resource-scoped message listing is not implemented by this storage adapter (${this.constructor.name}). Use an adapter that supports Observational Memory (pg, libsql, mongodb, convex) or disable observational memory.","messagePattern":"Resource-scoped message listing is not implemented by this storage adapter \\((.+?)\\)\\. Use an adapter that supports Observational Memory \\(pg, libsql, mongodb, convex\\) or disable observational memory\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/memory/base.ts","lineNumber":142,"sourceCode":"      id,\n      ...(title !== undefined ? { title } : {}),\n      ...(metadata !== undefined ? { metadata } : {}),\n    });\n  }\n\n  abstract deleteThread({ threadId }: { threadId: string }): Promise<void>;\n\n  abstract listMessages(args: StorageListMessagesInput): Promise<StorageListMessagesOutput>;\n\n  /**\n   * List messages by resource ID only (across all threads).\n   * Used by Observational Memory and LongMemEval for resource-scoped queries.\n   *\n   * @param args - Resource ID and pagination/filtering options\n   * @returns Paginated list of messages for the resource\n   */\n  async listMessagesByResourceId(_args: StorageListMessagesByResourceIdInput): Promise<StorageListMessagesOutput> {\n    throw new Error(\n      `Resource-scoped message listing is not implemented by this storage adapter (${this.constructor.name}). ` +\n        `Use an adapter that supports Observational Memory (pg, libsql, mongodb, convex) or disable observational memory.`,\n    );\n  }\n\n  abstract listMessagesById({ messageIds }: { messageIds: string[] }): Promise<{ messages: MastraDBMessage[] }>;\n\n  abstract saveMessages(args: { messages: MastraDBMessage[] }): Promise<{ messages: MastraDBMessage[] }>;\n\n  abstract updateMessages(args: {\n    messages: (Partial<Omit<MastraDBMessage, 'createdAt'>> & {\n      id: string;\n      content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };\n    })[];\n  }): Promise<MastraDBMessage[]>;\n\n  async deleteMessages(_messageIds: string[]): Promise<void> {\n    throw new Error(","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/memory/base.ts#L124-L160","documentation":"The base MemoryDomain storage class provides a default listMessagesByResourceId that always throws, because resource-scoped message listing (used by Observational Memory and LongMemEval) must be implemented by the concrete adapter. Only pg, libsql, mongodb, and convex support it.","triggerScenarios":"Using Observational Memory or resource-scoped message queries with a storage adapter that does not override listMessagesByResourceId, e.g. an in-memory store or a minimal custom adapter.","commonSituations":"Enabling observational memory without switching from the default/in-memory storage; swapping storage backends in dev; writing a custom adapter and missing this optional method.","solutions":["Switch to pg, libsql, mongodb, or convex storage","Disable observational memory in your Mastra config if resource-scoped listing isn't needed","Implement listMessagesByResourceId in your custom adapter","Query messages per-thread instead of per-resource"],"exampleFix":"// before\nnew Mastra({ storage: new InMemoryStore(), /* observational memory enabled */ });\n// after\nnew Mastra({ storage: new LibSQLStore({ url: 'file:./mastra.db' }), /* observational memory works */ });","handlingStrategy":"fallback","validationCode":"function supportsResourceMessages(storage: unknown): boolean {\n  return typeof (storage as any)?.listMessagesByResourceId === 'function' &&\n    (storage as any).listMessagesByResourceId !== (MastraStorage.prototype as any).listMessagesByResourceId;\n}","typeGuard":"function canListByResource(s: unknown): s is { listMessagesByResourceId(a: StorageListMessagesByResourceIdInput): Promise<StorageListMessagesOutput> } {\n  return supportsResourceMessages(s);\n}","tryCatchPattern":"try {\n  return await storage.listMessagesByResourceId({ resourceId });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Resource-scoped message listing is not implemented')) {\n    // fallback: aggregate messages across the resource's threads\n    return listMessagesAcrossThreads(resourceId);\n  }\n  throw e;\n}","preventionTips":["Check adapter capability before enabling Observational Memory","Prefer pg/libsql/mongodb/convex storage for resource-scoped features","Probe optional methods at app startup rather than mid-request"],"tags":["storage","unsupported-operation","observational-memory"],"backgroundTag":"method-not-implemented-by-adapter","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}