Skip to content

fix: v10 regressions found in side-by-side QA - #1965

Merged
isekovanic merged 9 commits into
release-v10from
fix/v10-qa-regressions
Oct 30, 2026
Merged

isekovanic merged 9 commits into
release-v10from
fix/v10-qa-regressions

Conversation

@oliverlaz

@oliverlaz oliverlaz commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Ticket: https://linear.app/stream/issue/REACT-1475

CLA

  • I have signed the Stream CLA (required).
  • Code changes are tested

Description of the changes, What, Why and How?

These fixes come from a manual side-by-side QA pass. It compared the React examples/vite app on stream-chat-react v14 + stream-chat v9 against v15 + this branch's v10. Each commit fixes one regression and adds a unit test that fails without the fix.

  • Failed edit, then Resend (fix(messageOperations)): retry() sent a failed edit as a new message. The server rejected it as a duplicate. The send path took that rejection for a delivered send, so the client showed the edited text as sent while the server kept the old text, and the rejection went unhandled. A failed edit is now sent again through update(). It is recognized by message_text_updated_at, which a failed send never has, so this also works after a reload.
  • Network-failed messages (fix(errors)): parseError did not set status when a request got no response. UI SDKs offer Edit and Discard on a failed message only when status === 0, as v9 UIs did, so those actions disappeared. Such errors now get status: 0. Only real transport failures get it: an axios error with no response that the caller did not cancel, or an OfflineError. A cancelled request and an error thrown by an integrator's own request handler keep no status (review follow-up).
  • Lists emptied by channel.hidden (fix(ChannelManager)): hiding every channel in a list drops its loaded page. When channels were shown again, they went only into the paginator's logical intervals. A list UI does not render those, so most channels never came back, and the example app's sideloaded section listed them twice. On channel.visible, a list with no loaded first page now re-queries it (debounced), as v9 did, but only when the shown channel matches the list's filters (review follow-up).
  • Thread participants (fix(thread)): updates to the parent message replaced the thread's participants with the message's thread_participants, which lists only repliers. This dropped the parent message's author. The two lists are now merged.
  • User agent (fix(scripts)): local builds take the version from git describe, whose tag is v-prefixed, so the user agent read stream-chat-js-vv10…. Published builds were not affected.

Checks: yarn lint, yarn types, yarn build and yarn test-unit (4836 passed). The suite reports 2 unhandled errors, and the base branch reports the same 2.

The stream-chat-react half is GetStream/stream-chat-react#3364 (same ticket).

Changelog

  • Retrying a failed message edit now sends an update instead of a duplicate send.
  • Transport failures stored on a failed message carry status: 0.
  • Channel lists recover after every listed channel was hidden and then shown again.
  • Thread participants keep the parent message's author.

A retried failed edit was re-sent as a new message. The server rejected it as a duplicate,
which the send path took for a delivered send: the edited text showed as sent while the
server kept the old one, and the rejection went unhandled.

retry() now replays a failed edit through update(). A failed edit is told apart by
message_text_updated_at, which a failed send never has, so this holds after a reload too.
parseError left status unset for transport failures (axios network errors, offline). UI
SDKs offer edit and discard on a failed message only for status 0, as v9 UIs did, so those
actions were missing.
…nel.visible

Hiding every channel of a list drops its loaded page. Channels shown again then landed only
in the paginator's logical intervals, which a list UI does not render, so most never came
back. A list without a loaded first page now re-queries it on channel.visible (debounced),
as v9 did. Also documents that a logical interval can be the active one.
Parent message updates replaced the thread's participants with the message's
thread_participants, which lists only repliers, dropping the parent's author. They are now
merged.
Local builds take the version from git describe, whose tags are v-prefixed, so the user
agent read stream-chat-js-vv10.x. Published builds use package.json and were not affected.
Comment thread src/ChannelManager.ts Resolved
Comment thread src/errors.ts Resolved
Comment thread src/ChannelManager.ts Resolved
parseError gave status 0 to any Error without a response, so an error thrown by an
integrator's own request handler read as a network failure, and the UI offered the edit and
discard actions meant for one. Only an axios error with no response that the caller did not
cancel, and an OfflineError, get it now.
On channel.visible, every list without a loaded page re-queried its first page, including
lists the shown channel cannot belong to, such as one that is simply empty. Only lists whose
filters match the channel re-query now.
Comment thread test/unit/ChannelManager.test.ts Resolved
…order

Hides three channels and shows them again newest, oldest, middle, with the list query running,
and asserts all three come back in sort order from one query. Without the reload only the first
channel shown survives.
…ached send

A send that failed after the server stored the message leaves a cached payload. When an edit
of that message later failed, Resend took the cached payload and sent the message again, which
the server rejects as a duplicate. A failed edit is now replayed as an edit first, and the stale
payload is dropped.

@MartinCupela MartinCupela left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, both points are fixed: the channel.visible re-query now only hits lists whose filters match the shown channel, and status 0 goes only to real transport failures. The failed-edit replay with a stale cached send in 0c22561 looks right too. Looks good.

@isekovanic
isekovanic merged commit b87d598 into release-v10 Oct 30, 2026
4 checks passed
@isekovanic
isekovanic deleted the fix/v10-qa-regressions branch October 30, 2026 13:44
github-actions Bot pushed a commit that referenced this pull request Oct 30, 2026
## [10.0.0-rc.28](v10.0.0-rc.27...v10.0.0-rc.28) (2026-10-30)

### Bug Fixes

* **deps:** bump [@stream-io](https://github.com/stream-io) toolkit packages to the .mjs/.cjs builds ([#1971](#1971)) ([aa97cf4](aa97cf4)), closes [GetStream/js-toolkit#58](https://github.com/GetStream/js-toolkit/issues/58)
* v10 regressions found in side-by-side QA ([#1965](#1965)) ([b87d598](b87d598))
@stream-ci-bot

Copy link
Copy Markdown

🎉 This PR is included in version 10.0.0-rc.28 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants