mastra-ai/mastra · error · KnowledgeNotFoundError

Knowledge record not found: ${id}

Error message

Knowledge record not found: ${id}

What it means

removeKnowledge() looks up the record by ID and throws KnowledgeNotFoundError('record', id) if no such record exists in the in-memory map. Deletion is a soft delete (sets deletedAt/deletedBy and enqueues a delete event); it only operates on records that exist.

Source

Thrown at packages/core/src/storage/domains/knowledge/inmemory.ts:396

    const records = [...this.#db.knowledgeRecords.values()]
      .filter(
        record =>
          record.sourceThreadId === input.sourceThreadId &&
          isKnowledgeScopeVisible(record.scope, scope) &&
          (input.includeDeleted || !record.deletedAt) &&
          (!input.after || record.id > input.after),
      )
      .sort((left, right) => left.id.localeCompare(right.id))
      .slice(0, limit + 1);
    return {
      records: records.slice(0, limit).map(cloneRecord),
      nextCursor: records.length > limit ? records[limit - 1]?.id : undefined,
    };
  }

  async removeKnowledge({ id, deletedBy }: { id: string; deletedBy: string }): Promise<KnowledgeRecord> {
    const record = this.#db.knowledgeRecords.get(id);
    if (!record) throw new KnowledgeNotFoundError('record', id);
    if (record.deletedAt) return cloneRecord(record);
    const updated = { ...record, deletedAt: new Date(), deletedBy };
    this.#db.knowledgeRecords.set(id, updated);
    this.#recordActivity('record-deleted', 'record', id, record.scope, record.sourceThreadId);
    this.#enqueue('record', id, 'delete', updated.deletedAt.toISOString(), record.scope);
    return cloneRecord(updated);
  }

  async restoreKnowledge({ id }: { id: string }): Promise<KnowledgeRecord> {
    const record = this.#db.knowledgeRecords.get(id);
    if (!record) throw new KnowledgeNotFoundError('record', id);
    if (!record.deletedAt) return cloneRecord(record);
    const updated = { ...record, deletedAt: undefined, deletedBy: undefined };
    this.#db.knowledgeRecords.set(id, updated);
    this.#recordActivity('record-restored', 'record', id, record.scope, record.sourceThreadId);
    this.#enqueue('record', id, 'upsert', createKnowledgeUlid(), record.scope);
    return cloneRecord(updated);
  }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the record exists (listKnowledge) before deleting, or treat not-found as already-deleted.
  2. Make the delete flow idempotent: catch KnowledgeNotFoundError and continue.
  3. Confirm the ID belongs to this storage instance/environment.
  4. If records were merged, delete via the surviving (terminal) node's records instead of stale IDs.

Example fix

// before
await storage.removeKnowledge({ id, deletedBy: user });
// after
try {
  await storage.removeKnowledge({ id, deletedBy: user });
} catch (e) {
  if (!(e instanceof KnowledgeNotFoundError)) throw e; // already gone — ok
}
Defensive patterns

Strategy: try-catch

Validate before calling

const records = await storage.listKnowledge({});
const exists = records.records.some(r => r.id === id && !r.deletedAt);
if (!exists) return; // nothing to delete

Try / catch

try {
  await storage.removeKnowledge({ id, deletedBy });
} catch (e) {
  if (e instanceof KnowledgeNotFoundError) return; // already gone
  throw e;
}

Prevention

When it happens

Trigger: Calling removeKnowledge({ id }) with an ID that was never appended, an ID from a different storage instance, or an already-purged record; double-processing a delete queue where the record was removed between calls.

Common situations: Workers consuming a queue where another worker already handled the record; tests asserting delete on fixtures from a prior store; UI holding a stale list while another session deleted the record.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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