mem0ai/mem0 · error · Error

Failed to delete memory with ID ${vectorId}

Error message

Failed to delete memory with ID ${vectorId}

What it means

During deleteVector, the Redis store checks the key exists, then calls DEL. Redis DEL returns the number of keys removed; a 0 return after the existence check passed means the delete did not actually happen (e.g. the key expired or was deleted concurrently between the two calls). The store throws rather than silently reporting success.

Source

Thrown at mem0-ts/src/oss/src/vector_stores/redis.ts:633

  }

  async delete(vectorId: string): Promise<void> {
    await this.initialize();
    try {
      // Check if memory exists first
      const key = `${this.indexPrefix}:${vectorId}`;
      const exists = await this.client.exists(key);

      if (!exists) {
        console.warn(`Memory with ID ${vectorId} does not exist`);
        return;
      }

      // Delete the memory
      const result = await this.client.del(key);

      if (!result) {
        throw new Error(`Failed to delete memory with ID ${vectorId}`);
      }

      console.log(`Successfully deleted memory with ID ${vectorId}`);
    } catch (error) {
      console.error("Error deleting memory:", error);
      throw error;
    }
  }

  async deleteCol(): Promise<void> {
    await this.initialize();
    await this.client.ft.dropIndex(this.indexName);
  }

  async list(
    filters?: SearchFilters,
    topK: number = 100,
  ): Promise<[VectorStoreResult[], number]> {

View on GitHub (pinned to 001c235229)

Solutions

  1. Treat this error as benign in concurrent-delete flows: catch it and verify with a follow-up EXISTS that the key is gone
  2. Make delete operations idempotent on the caller side (deduplicate by vector ID, or ignore failures after a successful existence re-check)
  3. Remove conflicting TTLs or external jobs that delete the same keyspace

Example fix

// before
await redisVs.deleteVector(id); // may throw on concurrent delete

// after
try {
  await redisVs.deleteVector(id);
} catch (e) {
  if (!(e.message.includes('Failed to delete'))) throw e;
  const still = await client.exists(`mem0:${id}`);
  if (still) throw e; // genuinely failed
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await redisVs.deleteVector(id);
} catch (e) {
  const msg = e instanceof Error ? e.message : '';
  if (!msg.includes('Failed to delete')) throw e;
  // concurrent delete: confirm the key is actually gone
  const stillExists = await rawClient.exists(`mem0:${id}`);
  if (stillExists) throw e;
}

Prevention

When it happens

Trigger: Two concurrent delete calls for the same memory ID where one wins; a key TTL expiring between the EXISTS check and the DEL call; manual/external deletion racing with the application.

Common situations: Duplicate delete requests from retries or idempotency-unaware clients; background cleanup jobs deleting the same keys; short TTLs configured on memory keys.

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/995a444597891646. Report an issue: GitHub.