toeverything/AFFiNE · error · ToolError
INVALID_CURSOR
INVALID_CURSOR
Error message
Invalid canvas cursor.
What it means
decodeCursor could not parse the supplied pagination cursor (malformed or corrupt base64/JSON), so the getter returns a non-retryable INVALID_CURSOR tool error; an absent cursor is fine (first page), only a provided-but-unparseable one fails.
Source
Thrown at packages/backend/server/src/plugins/copilot/tools/doc-canvas-read.ts:246
const canAccess = await ac
.user(options.user)
.workspace(options.workspace)
.doc(docId)
.can('Doc.Read');
if (!canAccess) {
return toolError('Doc Canvas Read Failed', 'Document access denied.', {
code: 'DOC_ACCESS_DENIED',
retryable: false,
locator: { doc_id: docId },
});
}
const projection = await docReader.getDocCanvas(options.workspace, docId);
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,View on GitHub (pinned to b4c8548c09)
Solutions
- Discard the cursor and start a new canvas read.
- Do not reuse cursors across sessions.
Defensive patterns
Strategy: validation
When it happens
Trigger: Returned as INVALID_CURSOR when a cursor value is supplied to doc_canvas_read but decodeCursor fails to parse it.
Common situations: A corrupted or hand-edited pagination cursor was passed to the canvas read. Restart the read without a cursor to get a fresh one.
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/b3e741326abb67a4.
Report an issue: GitHub.