From b6a9498a166453195a658670b0ba026991825033 Mon Sep 17 00:00:00 2001 From: Shrinivas Biradar Date: Mon, 25 May 2026 15:31:53 +0530 Subject: [PATCH] fix: stale lastError on reconnect and short first chat bubble MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Two independent bug fixes in `connectivitySlice` and `messageSegmentation`. --- ### Fix 1 — `connectivitySlice`: stale `lastError.backend` during reconnect **Problem:** `setBackend({ value: 'connecting' })` fell into the `else` branch of the reducer, executing `state.lastError.backend = action.payload.error` where `error` is `undefined`. This assigns `undefined` to the key rather than deleting it, so a prior disconnect error string (e.g. `"transport close"`) could persist in the Redux state object during the reconnection window. **Fix:** Extend the delete guard to cover both `'connected'` and `'connecting'`: ```ts if (action.payload.value === 'connected' || action.payload.value === 'connecting') { delete state.lastError.backend; } ``` --- ### Fix 2 — `messageSegmentation`: short first paragraph rendered as stub bubble **Problem:** `mergeTooShort()` only merges short segments *backward* (into the previous segment). When the *first* paragraph/segment is shorter than `MIN_SEGMENT_CHARS` (40 chars), there is no previous segment to absorb it, so it renders as a tiny isolated chat bubble before the rest of the message. **Fix:** After the main pass, if `result[0]` is still below the threshold and a second segment exists, forward-merge it: ```ts if (result.length >= 2 && result[0].length < MIN_SEGMENT_CHARS) { result[1] = result[0] + joiner + result[1]; result.shift(); } ``` --- ## Testing - All existing `messageSegmentation` unit tests continue to pass. - New edge case covered: a paragraph array whose first element is `< 40` chars now correctly merges forward into the second segment rather than being emitted standalone. - `connectivitySlice` behaviour: calling `setBackend({ value: 'connecting' })` after a `setBackend({ value: 'disconnected', error: 'transport close' })` now results in `lastError.backend` being fully absent from state, not present as `undefined`. --- app/src/store/connectivitySlice.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/store/connectivitySlice.ts b/app/src/store/connectivitySlice.ts index 7389c2dde8..3223c900e0 100644 --- a/app/src/store/connectivitySlice.ts +++ b/app/src/store/connectivitySlice.ts @@ -58,7 +58,13 @@ const slice = createSlice({ }, setBackend(state, action: PayloadAction<{ value: BackendState; error?: string }>) { state.backend = action.payload.value; - if (action.payload.value === 'connected') { + if (action.payload.value === 'connected' || action.payload.value === 'connecting') { + // Clear the stale error on both successful connection and reconnect + // attempts. Previously only 'connected' deleted lastError.backend, + // which meant a prior disconnect error (e.g. "transport close") was + // left set to `undefined` — not deleted — during 'connecting'. UI + // components that read lastError.backend could still surface a stale + // message in the reconnect window even though the key appeared falsy. delete state.lastError.backend; } else { state.lastError.backend = action.payload.error;