{"record":{"id":"93a70458ad2dc8cf","repo":"hcengineering/platform","slug":"failed-to-apply-ydoc-update","errorCode":null,"errorMessage":"Failed to apply ydoc update","messagePattern":"Failed to apply ydoc update","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"foundations/server/packages/collaboration/src/ydoc.ts","lineNumber":35,"sourceCode":"import {\n  AbstractType as YAbstractType,\n  Doc as YDoc,\n  applyUpdate,\n  encodeStateAsUpdate,\n  XmlElement as YXmlElement\n} from 'yjs'\n\nexport { XmlElement as YXmlElement, XmlText as YXmlText, AbstractType as YAbstractType } from 'yjs'\n\n/** @public */\nexport function yDocFromBuffer (buffer: Buffer, ydoc?: YDoc): YDoc {\n  ydoc ??= new YDoc({ guid: generateId(), gc: false })\n  try {\n    const uint8arr = new Uint8Array(buffer)\n    applyUpdate(ydoc, uint8arr)\n    return ydoc\n  } catch (err) {\n    throw new Error('Failed to apply ydoc update', { cause: err })\n  }\n}\n\n/** @public */\nexport function yDocToBuffer (ydoc: YDoc): Buffer {\n  const update = encodeStateAsUpdate(ydoc)\n  return Buffer.from(update.buffer)\n}\n\n/** @public */\nexport function yDocCopyXmlField (ydoc: YDoc, source: string, target: string): void {\n  const srcField = ydoc.getXmlFragment(source)\n  const dstField = ydoc.getXmlFragment(target)\n\n  ydoc.transact((tr) => {\n    // similar to XmlFragment's clone method\n    dstField.delete(0, dstField.length)\n    dstField.insert(0, srcField.toArray().map((item) => (item instanceof YAbstractType ? item.clone() : item)) as any)","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/server/packages/collaboration/src/ydoc.ts#L17-L53","documentation":"yDocFromBuffer wraps a Buffer of Yjs update data and applies it to a (possibly new) YDoc via applyUpdate. If applyUpdate throws (corrupt, truncated, or incompatible update bytes), the error is rethrown as 'Failed to apply ydoc update' with the original error attached as cause.","triggerScenarios":"Loading a collaboration ydoc from storage where the stored buffer is corrupted, truncated, empty/garbage, or was written by an incompatible Yjs/encoding version; passing a non-update buffer to yDocFromBuffer.","commonSituations":"Partial writes to blob storage leaving truncated ydoc data; manually edited or migrated collaboration blobs; version skew after a Yjs library upgrade; restoring from backups with damaged data.","solutions":["Inspect err.cause for the exact decode failure and verify the buffer's integrity (length, magic bytes) at the storage layer","Recover the document from an earlier snapshot/backup or regenerate it from the source-of-truth data","Delete/clean the corrupted collab blob so the system recreates the ydoc from a fresh state","Pin compatible Yjs versions between writer and reader to avoid encoding incompatibilities"],"exampleFix":"// before\nconst doc = yDocFromBuffer(corruptedBuffer)\n// after\nlet doc\ntry {\n  doc = yDocFromBuffer(buffer)\n} catch (err) {\n  console.error('ydoc corrupt, recreating:', err.cause)\n  doc = yDocFromBuffer(Buffer.alloc(0)) // fresh empty doc\n}","handlingStrategy":"try-catch","validationCode":"function isValidYdocBuffer(buf: Buffer): boolean {\n  return Buffer.isBuffer(buf) && buf.length > 0 && buf.length < 100 * 1024 * 1024 // reject empty/huge\n}","typeGuard":"function isNonEmptyBuffer(v: unknown): v is Buffer {\n  return Buffer.isBuffer(v) && v.length > 0\n}","tryCatchPattern":"try {\n  const doc = yDocFromBuffer(buffer)\n} catch (err) {\n  console.error('Corrupt ydoc:', (err as Error & { cause?: unknown }).cause)\n  // recover from snapshot/backup or recreate an empty doc\n  const doc = yDocFromBuffer(Buffer.alloc(0))\n}","preventionTips":["Validate buffer integrity (non-empty, expected length) before applying updates","Store ydocs atomically (write temp + rename) to avoid truncated blobs","Pin compatible Yjs versions across writer/reader services","Keep snapshots/backups so corrupted docs can be restored"],"tags":["yjs","collaboration","corrupt-data","deserialization"],"backgroundTag":"ydoc-update-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}