toeverything/AFFiNE · error · ToolError

REVISION_CHANGED

REVISION_CHANGED

Error message

The document changed after this cursor was issued.

What it means

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.

Source

Thrown at packages/backend/server/src/plugins/copilot/tools/doc-canvas-read.ts:259

    if (!projection) {
      return documentSyncPendingError(docId);
    }
    const cursor = cursorValue ? decodeCursor(cursorValue) : null;
    if (cursorValue && !cursor) {
      return toolError('Doc Canvas Read Failed', 'Invalid canvas cursor.', {
        code: 'INVALID_CURSOR',
        retryable: false,
        locator: { doc_id: docId },
      });
    }
    const fingerprint = targetHash(target);
    if (
      cursor &&
      (cursor.projectionVersion !== projection.version ||
        cursor.revision !== projection.revision ||
        cursor.targetHash !== fingerprint)
    ) {
      return toolError(
        'Doc Canvas Read Failed',
        'The document changed after this cursor was issued.',
        {
          code: 'REVISION_CHANGED',
          retryable: true,
          locator: { doc_id: docId, revision: projection.revision },
        }
      );
    }
    const selected = selectProjection(projection, target);
    const items = [
      ...selected.blocks.map(value => ({ kind: 'block' as const, value })),
      ...selected.elements.map(value => ({ kind: 'element' as const, value })),
    ].sort((left, right) => left.value.id.localeCompare(right.value.id));
    const offset = cursor?.offset ?? 0;
    const limit = Math.min(requestedLimit ?? 50, MAX_LIMIT);
    const page = items.slice(offset, offset + limit);
    const nextOffset = offset + page.length;

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Re-read the document and continue from a fresh cursor.
  2. Handle concurrent edits by restarting the iteration.
Defensive patterns

Strategy: fallback

When it happens

Trigger: Returned as REVISION_CHANGED when the cursor's projection version, revision, or target hash no longer matches the current canvas projection.

Common situations: The document was edited while the copilot was paging through its canvas. Retry the read; the error is marked retryable.


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/691177d7c895bc78. Report an issue: GitHub.