mastra-ai/mastra · error
Knowledge already exists: ${record.id}
Error message
Knowledge already exists: ${record.id} What it means
#appendKnowledge generates a record ID (or takes input.id) and inserts into knowledgeRecords. If a record with that ID already exists, it throws to enforce record-ID uniqueness — duplicate insertion would corrupt the upsert/delete changelog. This only happens when callers supply their own input.id that collides.
Source
Thrown at packages/core/src/storage/domains/knowledge/inmemory.ts:342
#appendKnowledge(input: AppendKnowledgeInput): KnowledgeRecord {
const node = nodeReferenceId(input.node);
const parent = this.#resolveTerminalNode(node);
if (!parent) throw new KnowledgeNotFoundError('node', node);
const scope = canonicalizeKnowledgeScope(input.scope);
assertKnowledgeScopeWithinCeiling(scope, input.maxScope);
const record: KnowledgeRecord = {
id: input.id ?? createKnowledgeUlid(),
node: parent.id,
text: input.text,
scope,
sourceThreadId: input.sourceThreadId,
capturedAt: new Date(),
when: input.when ? new Date(input.when) : undefined,
maxScope: input.maxScope,
metadata: input.metadata,
};
if (this.#db.knowledgeRecords.has(record.id)) throw new Error(`Knowledge already exists: ${record.id}`);
this.#db.knowledgeRecords.set(record.id, record);
this.#replaceMentions('record', record.id, record.text, input.resolutionScope, input.defaultScope);
parent.updatedAt = new Date();
this.#recordActivity('record-created', 'record', record.id, scope, input.sourceThreadId);
this.#enqueue('record', record.id, 'upsert', record.id, scope);
return cloneRecord(record);
}
async getKnowledge({
id,
includeDeleted = false,
}: {
id: string;
includeDeleted?: boolean;
}): Promise<KnowledgeRecord | null> {
const record = this.#db.knowledgeRecords.get(id);
if (!record || (record.deletedAt && !includeDeleted)) return null;
return cloneRecord(record);View on GitHub (pinned to 75dd419e61)
Solutions
- Omit input.id and let the storage generate a fresh ULID.
- Before appending with a custom ID, check whether the store already holds it (listKnowledge / get by id) and skip or update instead.
- Make retry logic idempotent: catch the duplicate and treat the existing record as the outcome.
- Namespace custom IDs (source system + original id) to avoid collisions.
Example fix
// before
await storage.appendKnowledge({ id: rec.id, node, text, scope }); // rec.id may already exist
// after
const existing = await storage.getKnowledge(rec.id);
if (!existing) await storage.appendKnowledge({ id: rec.id, node, text, scope }); Defensive patterns
Strategy: try-catch
Validate before calling
const existing = await storage.listKnowledge({ /* filters */ });
if (existing.records.some(r => r.id === desiredId)) skip = true; Try / catch
try {
await storage.appendKnowledge({ id: desiredId, node, text, scope });
} catch (e) {
if (e.message.startsWith('Knowledge already exists')) {
return; // idempotent retry: record already present
}
throw e;
} Prevention
- Omit input.id unless you need deterministic IDs for replay.
- Namespace client-supplied IDs by source system.
- Make import scripts idempotent by catching duplicates.
- Clear store state between test runs.
When it happens
Trigger: Calling appendKnowledge() with an explicit input.id equal to an existing record's ID; replaying the same append twice with deterministic IDs (e.g., derived from source content); concurrent appends using the same client-generated ID.
Common situations: Idempotent-retry logic reusing the same ID but not expecting a duplicate error; migration scripts importing records with original IDs into a store that already has some; test fixtures re-initialized without clearing the store.
Related errors
- Knowledge scope contains multiple ${level} entries
- Agent "${agentId}" is already connected to Slack. Disconnect
- MastraFactory: duplicate integration id '${integration.id}'
- MastraFactory: integration tool '${name}' from '${ownerId}'
- [FilesystemStorage] duplicate file path: ${file.path}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/57d6f7e922c37784.
Report an issue: GitHub.