mastra-ai/mastra · error

Message deletion is not supported by this storage adapter ($

Error message

Message deletion is not supported by this storage adapter (${this.constructor.name}). The deleteMessages method needs to be implemented in the storage adapter.

What it means

deleteMessages is an adapter-provided capability; the base class default throws to signal the active storage adapter has not implemented message deletion. Deleting messages requires adapter-specific data manipulation the abstract base cannot perform.

Source

Thrown at packages/core/src/storage/domains/memory/base.ts:160

    throw new Error(
      `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.`,
    );
  }

  abstract listMessagesById({ messageIds }: { messageIds: string[] }): Promise<{ messages: MastraDBMessage[] }>;

  abstract saveMessages(args: { messages: MastraDBMessage[] }): Promise<{ messages: MastraDBMessage[] }>;

  abstract updateMessages(args: {
    messages: (Partial<Omit<MastraDBMessage, 'createdAt'>> & {
      id: string;
      content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
    })[];
  }): Promise<MastraDBMessage[]>;

  async deleteMessages(_messageIds: string[]): Promise<void> {
    throw new Error(
      `Message deletion is not supported by this storage adapter (${this.constructor.name}). ` +
        `The deleteMessages method needs to be implemented in the storage adapter.`,
    );
  }

  /**
   * List threads with optional filtering by resourceId and metadata.
   *
   * @param args - Filter, pagination, and ordering options
   * @param args.filter - Optional filters for resourceId and/or metadata
   * @param args.filter.resourceId - Optional resource ID to filter by
   * @param args.filter.metadata - Optional metadata key-value pairs to filter by (AND logic)
   * @returns Paginated list of threads matching the filters
   */
  abstract listThreads(args: StorageListThreadsInput): Promise<StorageListThreadsOutput>;

  /**
   * Clone a thread and its messages to create a new independent thread.

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use or upgrade to a storage adapter that implements deleteMessages
  2. Implement deleteMessages in your custom adapter
  3. Skip/queue deletion and handle it in application code instead

Example fix

// before
class MyStore extends MastraStorage { /* no deleteMessages */ }
await storage.deleteMessages([id]); // throws
// after
class MyStore extends MastraStorage {
  async deleteMessages(messageIds: string[]): Promise<void> {
    await this.db.run('DELETE FROM messages WHERE id IN (?)', messageIds);
  }
}
Defensive patterns

Strategy: fallback

Validate before calling

function supportsDeleteMessages(storage: unknown): boolean {
  return typeof (storage as any)?.deleteMessages === 'function' &&
    (storage as any).deleteMessages !== (MastraStorage.prototype as any).deleteMessages;
}

Type guard

function canDeleteMessages(s: unknown): s is { deleteMessages(ids: string[]): Promise<void> } {
  return supportsDeleteMessages(s);
}

Try / catch

try {
  await storage.deleteMessages(ids);
} catch (e) {
  if (e instanceof Error && e.message.includes('Message deletion is not supported')) {
    logger.warn('deleteMessages unsupported by adapter; queuing for later');
    await deletionQueue.push(ids);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling deleteMessages(messageIds) on a storage adapter (or custom subclass) that doesn't override deleteMessages, e.g. memory message-deletion flows through the memory domain.

Common situations: Custom/minimal storage adapters; older adapters predating the deleteMessages API; tests using stub stores that don't implement deletion.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/208a7492f2d279a8. Report an issue: GitHub.