{"record":{"id":"1a8a1abd2d8bbc60","repo":"toeverything/AFFiNE","slug":"can-not-find-the-current-version-of-the-doc","errorCode":null,"errorMessage":"Can not find the current version of the doc.","messagePattern":"Can not find the current version of the doc\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/common/nbstore/src/storage/history.ts","lineNumber":85,"sourceCode":"    docId: string,\n    filter?: HistoryFilter\n  ): Promise<ListedHistory[]>;\n  abstract getHistory(\n    docId: string,\n    timestamp: Date\n  ): Promise<DocRecord | null>;\n  abstract deleteHistory(docId: string, timestamp: Date): Promise<void>;\n\n  async rollbackDoc(docId: string, timestamp: Date, editor?: string) {\n    const toSnapshot = await this.getHistory(docId, timestamp);\n    if (!toSnapshot) {\n      throw new Error('Can not find the version to rollback to.');\n    }\n\n    const fromSnapshot = await this.getDoc(docId);\n\n    if (!fromSnapshot) {\n      throw new Error('Can not find the current version of the doc.');\n    }\n\n    const change = this.generateRevertUpdate(fromSnapshot.bin, toSnapshot.bin);\n    await this.pushDocUpdate({ docId, bin: change, editor }, 'rollback');\n    // force create a new history record after rollback\n    await this.createHistory(docId, fromSnapshot);\n  }\n\n  // history can only be created upon update pushing.\n  protected abstract createHistory(\n    docId: string,\n    snapshot: DocRecord\n  ): Promise<void>;\n\n  protected generateRevertUpdate(\n    fromNewerBin: Uint8Array,\n    toOlderBin: Uint8Array\n  ): Uint8Array {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/common/nbstore/src/storage/history.ts#L67-L103","documentation":"The second guard in rollbackDoc: after the target history snapshot was found, the CURRENT doc record (getDoc(docId)) must also exist to compute the revert update (generateRevertUpdate(fromSnapshot.bin, toSnapshot.bin) needs both ends). If the live doc is missing, rollback cannot proceed and throws 'Can not find the current version of the doc.'","triggerScenarios":"Rolling back a docId whose live record was deleted (or never synced into this storage) while its history records still exist; local-first storage where the current doc hasn't been pulled yet; race where the doc is deleted between listing history and calling rollbackDoc.","commonSituations":"Doc moved/deleted in another client while a history tab stayed open; partial sync leaving history but not the current doc; deleting a doc and then attempting to restore content via rollback instead of a proper restore-from-history flow.","solutions":["Check getDoc(docId) before offering rollback; if absent, use a restore/create flow (create the doc from the snapshot bin) instead of rollbackDoc.","Refresh/retry after sync completes if the doc exists on the server but not locally.","Handle the error in UI as 'doc no longer exists' with an option to restore it as a new doc from the chosen version."],"exampleFix":"// before\nawait history.rollbackDoc(docId, entry.timestamp); // throws if live doc deleted\n\n// after\nconst current = await history.getDoc(docId);\nif (!current) {\n  await restoreAsNewDoc(entry); // create doc from snapshot bin\n} else {\n  await history.rollbackDoc(docId, entry.timestamp);\n}","handlingStrategy":"validation","validationCode":"const current = await history.getDoc(docId);\nif (!current) throw new Error('doc missing — restore from snapshot instead of rollback');\nawait history.rollbackDoc(docId, ts);","typeGuard":"const docExists = async (docId: string): Promise<boolean> => (await history.getDoc(docId)) !== null;","tryCatchPattern":"try { await history.rollbackDoc(docId, ts); } catch (e) { if (e instanceof Error && e.message === 'Can not find the current version of the doc.') { /* offer restore-as-new-doc from snapshot */ } throw e; }","preventionTips":["Guard rollback with getDoc() in the UI action","Re-check existence after sync completes in multi-client setups","Provide a restore-to-new-doc path for deleted documents with surviving history"],"tags":["history","snapshot","rollback","missing-doc","affine"],"backgroundTag":"missing-document-record","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}