mastra-ai/mastra · error
Cannot update merged knowledge node: ${input.id}
Error message
Cannot update merged knowledge node: ${input.id} What it means
The target node has already been merged into another node (mergedInto is set). Merged nodes are tombstones — their content is owned by the merge target — so updating them is forbidden to avoid diverging from the terminal node.
Source
Thrown at packages/core/src/storage/domains/knowledge/inmemory.ts:208
!cursor ||
node.updatedAt < cursor.updatedAt ||
(node.updatedAt.getTime() === cursor.updatedAt.getTime() &&
(node.name > cursor.name || (node.name === cursor.name && node.id > cursor.id))),
)
.slice(0, input.limit ?? 100)
.map(cloneNode);
}
async updateNode(input: UpdateKnowledgeNodeInput): Promise<KnowledgeNode> {
return this.#runAtomicMutation(() => this.#updateNode(input));
}
#updateNode(input: UpdateKnowledgeNodeInput): KnowledgeNode {
assertKnowledgeDescriptionWithinBound(input.description);
const existing = this.#db.knowledgeNodes.get(input.id);
if (!existing) throw new KnowledgeNotFoundError('node', input.id);
if (existing.version !== input.version) throw new KnowledgeConflictError(input.id);
if (existing.mergedInto) throw new Error(`Cannot update merged knowledge node: ${input.id}`);
const scope = canonicalizeKnowledgeScope(input.scope ?? existing.scope);
const name = (input.name ?? existing.name).trim();
const oldKey = recordKey(existing.name, existing.scope);
const newKey = recordKey(name, scope);
const collision = this.#db.knowledgeNodeKeys.get(newKey);
if (collision && collision !== input.id) throw new Error(`Knowledge node already exists in scope: ${name}`);
const updated: KnowledgeNode = {
...existing,
name,
kind: input.kind ?? existing.kind,
content: input.content ?? existing.content,
description: input.description ?? existing.description,
scope,
version: existing.version + 1,
updatedAt: new Date(),
};View on GitHub (pinned to 75dd419e61)
Solutions
- Resolve the merge chain and update the terminal (target) node instead of the tombstone
- Skip the update if the node is merged (treat as already superseded)
- Re-check freshness with getNode before updating, and handle mergedInto explicitly in your workflow
Example fix
// before
await store.updateNode({ id: sourceId, version, description });
// after
const node = await store.getNode({ id: sourceId, resolutionScope: scope });
const target = node.mergedInto ?? node.id;
await store.updateNode({ id: target, version: (await store.getNode({ id: target, resolutionScope: scope })).version, description }); Defensive patterns
Strategy: type-guard
Validate before calling
const node = await store.getNode({ id, resolutionScope: scope });
if (node.mergedInto) throw new Error(`node ${id} was merged into ${node.mergedInto}; update the target instead`); Type guard
function isMerged(node: KnowledgeNode): boolean {
return typeof node.mergedInto === 'string' && node.mergedInto.length > 0;
} Try / catch
try {
await store.updateNode({ id, version, ...patch });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Cannot update merged knowledge node')) {
const terminal = await resolveTerminal(id);
await store.updateNode({ id: terminal.id, version: terminal.version, ...patch });
} else throw e;
} Prevention
- Check mergedInto on the node before every update and follow the chain to the terminal
- After merges, invalidate cached node references in long-running workflows
- Design dedup flows so updates always target the merge destination
- Track merge events in your app and re-map stored ids to terminal ids
When it happens
Trigger: Calling updateNode({ id }) on a node that a previous mergeNodes(sourceId=id, targetId=...) call marked as merged, while its stale version still passes the version check (or the caller replayed an old update).
Common situations: A workflow captured the node before a merge happened elsewhere; retry logic re-applying an old update; agents sharing a knowledge store where one merged a duplicate into another.
Related errors
- Knowledge node not found: ${id}
- SCHEDULES_INVALID_WORKFLOW_PATCH
- Merged knowledge node is not visible from scope: ${input.nam
- Knowledge node already exists: ${node.id}
- Knowledge record version conflict: ${id}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4118554cdefbce92.
Report an issue: GitHub.