facebook/lexical · error
Unexpected delta format
Error message
Unexpected delta format
What it means
CollabElementNode.applyChildrenYjsDelta maps Yjs delta operations ('insert' of Y.Text/Y.Map/Y.XmlElement or string, 'delete', 'retain') into Lexical mutations. Any delta component lacking a recognized 'insert'/'delete'/'retain' key indicates a malformed or foreign delta and the binding throws rather than corrupting the document.
Source
Thrown at packages/lexical-yjs/src/CollabElementNode.ts:273
children.splice(nodeIndex + 1, 0, collabNode);
// The insert that triggers the text split might not be a text node. Need to keep a
// reference to the remaining text so that it can be added when we do create one.
pendingSplitText = spliceString(text, 0, splitIdx, '');
} else {
children.splice(nodeIndex, 0, collabNode);
}
if (
pendingSplitText !== null &&
collabNode instanceof CollabTextNode
) {
// Found a text node to insert the pending text into.
collabNode._text = pendingSplitText + collabNode._text;
pendingSplitText = null;
}
currIndex += 1;
}
} else {
throw new Error('Unexpected delta format');
}
}
}
syncChildrenFromYjs(binding: Binding): void {
// Now diff the children of the collab node with that of our existing Lexical node.
const lexicalNode = this.getNode();
if (lexicalNode === null) {
// The Lexical node was concurrently removed (e.g. by a remote edit or undo)
// while we still have a pending change for it. There is nothing to reconcile
// into Lexical; this collab node will be cleaned up when its parent syncs.
return;
}
const key = lexicalNode.__key;
const prevLexicalChildrenKeys = $createChildrenArray(lexicalNode, null);
const nextLexicalChildrenKeys: NodeKey[] = [];
const lexicalChildrenKeysLength = prevLexicalChildrenKeys.length;View on GitHub (pinned to 76a22dcba9)
Solutions
- Verify the Yjs version matches what @lexical/yjs expects (check lockfiles for duplicate/hoisted yjs copies).
- Do not fabricate or post-process deltas; rely on Y.Text.observe observers and let @lexical/yjs apply transactions itself.
- Inspect the offending delta (log it before applyChildrenYjsDelta) to find who produced the malformed operation.
- If using syncLexical/updateFromYjs manually, ensure deltas come straight from Yjs events and contain only insert/delete/retain.
Defensive patterns
Strategy: validation
Validate before calling
for (const d of delta) {
const keys = Object.keys(d).filter(k => ['insert','delete','retain'].includes(k));
if (keys.length !== 1) throw new Error('Malformed delta component: ' + JSON.stringify(d));
} Type guard
function isWellFormedDelta(delta: Y.YEvent['delta']): boolean {
return delta.every(d =>
['insert', 'delete', 'retain'].filter(k => k in d).length === 1);
} Try / catch
try {
syncYjsChangesToLexical(provider, binding, true);
} catch (e) {
if (e.message === 'Unexpected delta format') {
// resync from scratch
resetProviderState(provider, binding);
} else throw e;
} Prevention
- Don't hand-craft or rewrite Yjs deltas — let Yjs observers feed @lexical/yjs
- Pin a single yjs version across the app (watch for duplicate lockfile entries)
- Log delta contents when wiring custom sync middleware
- Test collaboration between all client versions before deploying custom nodes
When it happens
Trigger: Applying a Yjs transaction whose delta contains an operation without exactly one of insert/delete/retain; feeding a hand-crafted or third-party-transformed Y.Text delta into syncLexical/updateFromYjs; version mismatches where a Yjs patch format changed.
Common situations: Custom middleware or CRDT proxies rewriting deltas; passing Y.Event deltas directly instead of using the library's observer pipeline; mixing y-protocols versions or applying deltas from an incompatible Yjs release.
Related errors
- $createOrUpdateNodeFromYElement: Node ${type} is not registe
- $createTextNodesFromYText: Node ${type} is not registered
- $createTextNodesFromYText: Node ${type} is not a TextNode
- Invalid state key: ${key}
- node name mismatch!
AI-assisted analysis of facebook/lexical@76a22dcba9 (2026-08-31).
Data as JSON: /api/errors/9bb1583c09dd9521.
Report an issue: GitHub.