{"record":{"id":"691177d7c895bc78","repo":"toeverything/AFFiNE","slug":"revision-changed","errorCode":"REVISION_CHANGED","errorMessage":"The document changed after this cursor was issued.","messagePattern":"The document changed after this cursor was issued\\.","errorType":"error_code","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/backend/server/src/plugins/copilot/tools/doc-canvas-read.ts","lineNumber":259,"sourceCode":"    if (!projection) {\n      return documentSyncPendingError(docId);\n    }\n    const cursor = cursorValue ? decodeCursor(cursorValue) : null;\n    if (cursorValue && !cursor) {\n      return toolError('Doc Canvas Read Failed', 'Invalid canvas cursor.', {\n        code: 'INVALID_CURSOR',\n        retryable: false,\n        locator: { doc_id: docId },\n      });\n    }\n    const fingerprint = targetHash(target);\n    if (\n      cursor &&\n      (cursor.projectionVersion !== projection.version ||\n        cursor.revision !== projection.revision ||\n        cursor.targetHash !== fingerprint)\n    ) {\n      return toolError(\n        'Doc Canvas Read Failed',\n        'The document changed after this cursor was issued.',\n        {\n          code: 'REVISION_CHANGED',\n          retryable: true,\n          locator: { doc_id: docId, revision: projection.revision },\n        }\n      );\n    }\n    const selected = selectProjection(projection, target);\n    const items = [\n      ...selected.blocks.map(value => ({ kind: 'block' as const, value })),\n      ...selected.elements.map(value => ({ kind: 'element' as const, value })),\n    ].sort((left, right) => left.value.id.localeCompare(right.value.id));\n    const offset = cursor?.offset ?? 0;\n    const limit = Math.min(requestedLimit ?? 50, MAX_LIMIT);\n    const page = items.slice(offset, offset + limit);\n    const nextOffset = offset + page.length;","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/plugins/copilot/tools/doc-canvas-read.ts#L241-L277","documentation":"The cursor's stored projectionVersion/revision/targetHash no longer match the current canvas fingerprint, meaning the document changed since the cursor was issued; continuing would return inconsistent data, so a non-retryable stale-cursor tool error is returned.","triggerScenarios":"Returned as REVISION_CHANGED when the cursor's projection version, revision, or target hash no longer matches the current canvas projection.","commonSituations":"The document was edited while the copilot was paging through its canvas. Retry the read; the error is marked retryable.","solutions":["Re-read the document and continue from a fresh cursor.","Handle concurrent edits by restarting the iteration."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}