Skip to content

🐛 Stop stale remote presence catch-up looping forever - #745

Merged
alecgibson merged 1 commit into
mainfrom
fix/issue-732-presence-catch-up-loop
Oct 8, 2026
Merged

alecgibson merged 1 commit into
mainfrom
fix/issue-732-presence-catch-up-loop

Conversation

@alecgibson

Copy link
Copy Markdown
Collaborator

Fixes #732

At the moment, RemoteDocPresence ignores errors returned by ot.transformPresence() when catching up stale presence. Since presence.v isn't advanced on error, the loop never ends:

  1. A peer sends a stale presence with t: null and no d
  2. An op is submitted to the doc
  3. The peer resends the stale presence
  4. The receiving client hangs, freezing the tab

This change drops the pending presence and emits the error instead, as we already do in _transformAgainstOp(). ot.transformPresence() also now returns a ShareDBError like the rest of ot, since that's what the presence 'error' event is documented to emit.

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

@coveralls

coveralls commented Oct 6, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 97.854% (+0.003%) from 97.851% — fix/issue-732-presence-catch-up-loop into main

Comment thread test/client/presence/doc-presence.js
Fixes #732

At the moment, `RemoteDocPresence` ignores errors returned by
`ot.transformPresence()` when catching up stale presence. Since
`presence.v` isn't advanced on error, the loop never ends:

 1. A peer sends a stale presence with `t: null` and no `d`
 2. An op is submitted to the doc
 3. The peer resends the stale presence
 4. The receiving client hangs, freezing the tab

This change drops the pending presence and emits the error instead,
as we already do in `_transformAgainstOp()`. `ot.transformPresence()`
also now returns a `ShareDBError` like the rest of `ot`, since that's
what the presence `'error'` event is documented to emit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@alecgibson
alecgibson force-pushed the fix/issue-732-presence-catch-up-loop branch from 030efd7 to a529e19 Compare October 8, 2026 13:47
@alecgibson
alecgibson requested a balanced review from Copilot October 8, 2026 13:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The fix terminates the failing catch-up path and includes focused regression coverage.

0 open findings

What changed in this PR

Prevents infinite stale-presence catch-up loops by handling transformation failures safely.

Changes:

  • Drops untransformable pending presence and stops operation caching.
  • Returns ShareDBError instances from presence transformations.
  • Adds regression coverage for recovery after malformed presence.
File Description
lib/​client/​presence/​remote-doc-presence.js Handles catch-up transformation errors.
lib/​ot.js Standardizes transformation errors.
test/​client/​presence/​doc-presence.js Tests error emission and recovery.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

@alecgibson
alecgibson marked this pull request as ready for review October 8, 2026 13:57
@alecgibson
alecgibson requested a review from dawidreedsy October 8, 2026 13:57
@alecgibson
alecgibson merged commit 3868002 into main Oct 8, 2026
9 checks passed
@alecgibson
alecgibson deleted the fix/issue-732-presence-catch-up-loop branch October 8, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remote presence catch-up can loop forever, freezing the client tab

4 participants