🐛 Bug Report: INVALID_STATE_ERROR crash after background + network disconnect + foreground cycle
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- react-native, typescript
Research direction
Start in src/client.ts:259 at createHeartbeat() and trace how the Realtime socket and heartbeat are recreated on open events. Reproduce the background, network disconnect, reconnect, and foreground cycle, then verify that heartbeat timers do not accumulate and that sending is safe during socket reconnection. Done means the connection resumes without an INVALID_STATE_ERROR crash.
Written by the indexing model from the issue text.
Description
👟 Reproduction steps
- Open the app with an active Realtime subscription
- Disconnect the network
- Send the app to the background
- Reconnect the network and wait for the connection to fully re-establish
- Bring the app back to the foreground
👍 Expected behavior
When an app using Realtime is sent to the background while the network is disconnected, and then brought back to the foreground after reconnecting, the app hard crashes with Uncaught Error: INVALID_STATE_ERROR originating from a WebSocket send() call inside the heartbeat interval.
The Realtime connection should resume normally.
👎 Actual Behavior
Hard crash: Uncaught Error: INVALID_STATE_ERROR thrown from socket.send() inside the heartbeat interval.
Most likely root cause:
There are two bugs in createHeartbeat() (src/client.ts:259):
createHeartbeat: () => {
if (this.realtime.heartbeat) {
clearTimeout(this.realtime.heartbeat); // ❌ Bug 1
}
this.realtime.heartbeat = window?.setInterval(() => {
this.realtime.socket?.send(JSON.stringify({ // ❌ Bug 2
type: 'ping'
}));
}, 20_000);
},
Bug 1 — clearTimeout cannot cancel a setInterval
this.realtime.heartbeat is assigned via setInterval, but clearTimeout is used to cancel it. These use separate timer registries — clearTimeout silently does nothing when given an interval ID. As a result, every call to createHeartbeat() (which happens on every open event) stacks a new interval on top of all previous ones without ever clearing them.
Bug 2 — no readyState guard before send()
The accumulated intervals all call socket.send() unconditionally. When the socket is in CLOSING (2) or CLOSED (3) state — which happens transiently during any reconnect — send() throws INVALID_STATE_ERROR.
Fix
createHeartbeat: () => {
if (this.realtime.heartbeat !== undefined) {
clearInterval(this.realtime.heartbeat); // ✅ matches setInterval
this.realtime.heartbeat = undefined;
}
this.realtime.heartbeat = window?.setInterval(() => {
if (this.realtime.socket?.readyState === WebSocket.OPEN) { // ✅ guard
this.realtime.socket.send(JSON.stringify({ type: 'ping' }));
}
}, 20_000);
},
🎲 Appwrite version
Version 0.7.x
💻 Operating system
MacOS
🧱 Your Environment
No response
👀 Have you spent some time to check if this issue has been raised before?
- I checked and didn't find similar issue
🏢 Have you read the Code of Conduct?
- I have read the Code of Conduct
- Dominant language
- TypeScript
- Stars
- 4.3k
- Forks
- 36
- Avg merge
- 8h 20m
- Merged PRs (30d)
- 2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from appwrite/sdk-for-react-native
-
🐛 Bug Report: Storage uploads fail on Expo SDK 55 because the SDK imports a removed FileSystem API Open
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
appwrite/sdk-for-react-native#112 · 3 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 65/100
appwrite/sdk-for-react-native#115 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 65/100
appwrite/sdk-for-react-native#114 ·
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 58/100
appwrite/sdk-for-react-native#113 · 1 comment ·
-
bug
appwrite/sdk-for-react-native#73 · 2 comments · 1 assignee ·
All issues in appwrite/sdk-for-react-native
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100