Skip to content

fix(channels): show Add and Send message errors above the Manage members list - #2421

Merged
matt2e merged 6 commits into
mainfrom
non-visible-error-when-adding-a-member
Nov 4, 2026
Merged

matt2e merged 6 commits into
mainfrom
non-visible-error-when-adding-a-member

Conversation

@matt2e

@matt2e matt2e commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Problem

In a long channel, Manage members rendered a refused Add (with Retry), "Opening conversation…", a failed Send message and a failed Copy link after the last member group, inside the scrolling member list. The action looked like it did nothing until you scrolled to the bottom.

member-errors-before-after.mp4

Before: main at the merge-base (0b2dfbf). After: this branch. Both use the same script and timing in a 61-person channel, in Chromium at 960×720.

What changed

  • Errors above the list. The four action messages now render just after the existing administration error, before region "Member list". No state changes. Solo share feedback and the hidden status announcement stay where they were.
  • Refusals grouped by reason. A refused team add gives one alert per distinct reason, not one per agent. The alert names up to three people, then "and N more", and has a single Retry ("Retry adding Ada and Cy"). Team add and group Retry share one addAll path (Promise.allSettled) and announce one combined notice. Names are sorted and formatted with Intl.ListFormat. Retry returns focus to the search field. Solo agents keep one alert each.
  • Containment fix (position: relative on .memberList). Moving the errors wasn't enough. The pager's sr-only "Page" span is absolutely positioned, and its containing block was the overflow: hidden dialog body. On a long roster that gave the body about 2,000 px of hidden scroll overflow. Highlighting a search match scrolled the body, and inserting an alert moved it further through scroll anchoring. No wheel could undo it, so the search field and the new alert ended up above the visible area. Making .memberList the containing block leaves the body with nothing to scroll. The dialog's other positioned descendants (sr-only text, and a hit target already inside its own relative parent) don't depend on the old containing block.
  • docs/channels.md describes the new placement and grouping.
Refused add Send message failed
Step 4: on main the refusal is a 20% sliver at the bottom of the list; on this branch it sits under the search field, fully in view Step 6: main shows no error in view; this branch shows the refusal and the Send message error together above the list

Tests

  • Vitest (MemberAdministration.test.tsx, ChannelMembersDialog.test.tsx):
    • Each message renders outside and before the member list.
    • One reason gives one alert whose Retry adds every agent; two reasons give two alerts.
    • A partial retry leaves only the agent that is still refused.
    • Four refusals read "Ada, Bo, Cy, and 1 more".
    • Retry focus lands on the search field.
    • The placement and grouping cases fail on the previous dialog.
  • Browser journey, added: tests/browser/channel-members-errors.spec.mjs (Chromium and WebKit).
    • Why it's a browser test: the defect is real layout, scroll anchoring and containing-block geometry, which jsdom can't model.
    • What it checks: on a 60-member roster with a highlighted "Sam" search, the dialog body has no hidden overflow. A refused Add and a later failed Send message both stay fully in view with the search field.
    • Fail-then-pass: without the containment rule it fails with 2,038 px of hidden overflow.
    • Prior run: passed in both engines with --repeat-each=3.
  • channel-members-focus.spec.mjs: one locator updated for the new Retry name.

Typecheck, lint and the related Vitest and browser files passed locally at 6383cec. CI hasn't been checked yet.

Known limits

  • 200% text: three refusals with different reasons still push the search field out of view, at both 960 px and 480 px. This is the layout's whole-body fallback for enlarged text, not the overflow bug. A capped, separately scrolling feedback block was measured and made it worse (it hid the newest alert), so it was left out.
  • Relabel: after a refused add, clearing the search still changes the refusal's label from "Sam:" to "npub…". Now that the alert is always visible, this is easier to notice. It's a follow-up (profile ensure for refused keys).
  • Rest of the Members dialog plan isn't in this PR:
    • an invite route when a search finds no match
    • the stable error label above
    • a caption for locked General access
    • matching docs in docs/buzz-help.md
  • Not checked: the native desktop app, dark theme, VoiceOver (a group alert is announced again when it shrinks), and WebKit recordings.
  • Shared dialog styles: the shared .buzz-dialog-body still uses overflow: hidden. Switching to overflow: clip would close this class of bug, but that's a design-system change for its owners.

🤖 Generated with Claude Code

matt2e and others added 6 commits November 4, 2026 22:51
In a long Manage members list, a refused Add (with Retry), "Opening
conversation…", a Send message failure and a Copy link failure rendered
after the last member group inside the scrolling Member list, so they
appeared below the fold and the action looked like it did nothing.

Render them outside and before the Member list region, right after the
existing administration error. No state changes; Solo share feedback
and the hidden status announcement stay where they were.

The new MemberAdministration case checks that each message is outside the
list and before it in document order, and fails on the previous layout.
Its setup now exposes the community writer and gives the session an
in-memory outbox (as ChannelMembersDialog tests do), because jsdom has
no IndexedDB and a plain Add otherwise fails before publishing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
A refused team add produced one alert and Retry per agent above the list,
so a few refusals with the same reason could push the member list and
search field out of view.

Group memberAdditions errors by identical message: one alert names the
people (up to three, then "and N more") and its one Retry resubmits every
key in the group. A single refusal still reads "Sam: blocked: … Retry";
the button's accessible name says who it retries ("Retry adding Sam").
Names come from label() with the team row's fallback; label() is unchanged.
Refusals, the opening status, the DM error and the copy failure share one
wrapper with a tighter gap than the layout's sections.

Tests: a refused team add with one reason gives one alert whose Retry
adds both agents; two reasons give two alerts. Both fail on the previous
dialog. Existing Retry locators use the new accessible name.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
A group Retry called the row Add path per key, so each success
overwrote the previous notice and recorded a search choice for every
agent. The Retrying… state was unreachable, because a pending addition
leaves the alert.

Retry a group like a team add: await every key with Promise.allSettled
and announce one combined notice ("Ada and Cy are in the channel.").
A single refusal keeps the Add path. Format names with Intl.ListFormat,
sorted by label so the text is stable, and keep one Retry per solo
agent, which joins directly. Drop the unreachable Retrying… branch.

Tests cover a partial retry (only "Cy: Invitation denied" remains, with
"Retry adding Cy") and a four-agent refusal ("Ada, Bo, Cy, and 1 more").

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
…ries

addTeam and the group Retry ran the same allSettled loop with different
notices. Fold both into addAll(keys, done), with the done text passed
from render. The group Retry now focuses the search field first, where
Add lands, so the next step is the search.

Tests: Retry leaves focus on the search field; the partial-retry case
scopes its "no Ada" check to the alerts and waits for Ada's addition to
land before asserting that no group notice appears. docs/channels.md
says Solo agents keep one alert each.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
The errors above the member list could still leave the viewport. The
pager's sr-only "Page" span is absolutely positioned, and its containing
block was the overflow: hidden dialog body, which gave the body ~2,600 px
of hidden scroll overflow on a long roster. Highlighting a search match
scrolled that body 24 px, and inserting an alert above the list moved it
by the alert's height through scroll anchoring. No wheel could bring it
back, so the search field and the refusal sat above the visible area.

Make .memberList the containing block, so the body has nothing to
scroll. Nothing in the dialog relied on the old containing block: the
other positioned descendants are sr-only text and a hit target already
contained by its own relative parent.

A browser journey covers it in Chromium and WebKit: on a 60-member
roster with a highlighted "Sam" search, a refused Add and a later
failed Send message both stay fully in view with the search field. It
fails on the previous stylesheet (refusal 0.70 in view).

A bounded feedback block (max-block-size with its own overflow) was
measured at 200% text and left out: it hides the newest alert and does
not keep the search field in view.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
…ember errors journey

Check the root cause directly: once the roster rows render, the dialog
body's scrollHeight minus clientHeight is 0. Pin the roster heading to
"People · 61", drop the add gate and the "Adding…" check it existed for,
and drop the scrollTop writes, which the click's own scrolling made
redundant. Without the containment rule the journey fails here first,
with 2,038 px of hidden overflow.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
@matt2e
matt2e marked this pull request as ready for review November 4, 2026 14:08
@matt2e
matt2e requested a review from a team as a code owner November 4, 2026 14:08

@kazemek21 kazemek21 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.

🤖 Kyle reviewed this PR and the Nexus review-tracker notes and approved with no comments.

Posted by Codex (gpt-6.1-sol) on behalf of kylez

@matt2e
matt2e merged commit 6f4d8ad into main Nov 4, 2026
42 checks passed
@matt2e
matt2e deleted the non-visible-error-when-adding-a-member branch November 4, 2026 22:27
johnmatthewtennant added a commit that referenced this pull request Nov 4, 2026
* origin/main: (38 commits)
  fix(browser): load scheme-less address input over https, falling back to http (#2467)
  fix(identity): stop one-click key unlinks and show the linked backed-up key (#2486)
  fix(test): observe coordination transition events (#2297)
  fix(profiles): keep the next view's profile reads through a shrink (#2395)
  fix(channels): show Add and Send message errors above the Manage members list (#2421)
  fix(threads): keep reply hooks off agent activity bubbles (#2422)
  fix(channels): offer only Copy link in a not-joined preview's sidebar actions (#2425)
  test: scope row menu placement checks to active section rows (#2493)
  feat(relay): detach channel windows to a point in history (#2042)
  feat(identity): decide a missing backup choice from community membership (#2378)
  Offer Builderlab decisions in FI builds (#2227)
  feat(inbox): preview recent Inbox activity when hovering the sidebar row (#2347)
  Add collapsible Solo and Team sidebar sections (#2296)
  fix(codex): open long Codex transcripts a page of items at a time (#2259)
  Keep Solo model and effort choices per chat (#2342)
  feat(sidebar): smooth channel reordering with bounded motion (#2108)
  Connect legacy agents from DMs and channel mentions (#2423)
  fix: exclude muted channels from sidebar unread scroll indicators (#2335)
  fix(claude-code): open long Claude transcripts a page at a time (#2428)
  feat(solo): share chats as view only (#2375)
  ...
damienrj added a commit to damienrj/buzz-app that referenced this pull request Nov 4, 2026
…-clone-auth-ab8b97

* origin/main:
  fix(browser): load scheme-less address input over https, falling back to http (block#2467)
  fix(identity): stop one-click key unlinks and show the linked backed-up key (block#2486)
  fix(test): observe coordination transition events (block#2297)
  fix(profiles): keep the next view's profile reads through a shrink (block#2395)
  fix(channels): show Add and Send message errors above the Manage members list (block#2421)
  fix(threads): keep reply hooks off agent activity bubbles (block#2422)
  fix(channels): offer only Copy link in a not-joined preview's sidebar actions (block#2425)
  test: scope row menu placement checks to active section rows (block#2493)
  feat(relay): detach channel windows to a point in history (block#2042)

Signed-off-by: damienrj <[email protected]>
wpfleger96 added a commit that referenced this pull request Nov 4, 2026
…-nip-fi

* origin/main:
  fix(identity): stop one-click key unlinks and show the linked backed-up key (#2486)
  fix(test): observe coordination transition events (#2297)
  fix(profiles): keep the next view's profile reads through a shrink (#2395)
  fix(channels): show Add and Send message errors above the Manage members list (#2421)
  fix(threads): keep reply hooks off agent activity bubbles (#2422)
  fix(channels): offer only Copy link in a not-joined preview's sidebar actions (#2425)
  test: scope row menu placement checks to active section rows (#2493)
  feat(relay): detach channel windows to a point in history (#2042)

# Conflicts:
#	src/app/IdentitySettings.test.tsx
#	src/app/IdentitySettings.tsx
#	src/app/Settings.tsx
wpfleger96 added a commit that referenced this pull request Nov 4, 2026
…r-load-perf

* origin/main: (31 commits)
  test: fix invitation and coordination checks on main (#2517)
  perf(search): name searched people from the profile search response (#2353)
  Use the merge queue for pull requests that require it (#2452)
  fix(browser): load scheme-less address input over https, falling back to http (#2467)
  fix(identity): stop one-click key unlinks and show the linked backed-up key (#2486)
  fix(test): observe coordination transition events (#2297)
  fix(profiles): keep the next view's profile reads through a shrink (#2395)
  fix(channels): show Add and Send message errors above the Manage members list (#2421)
  fix(threads): keep reply hooks off agent activity bubbles (#2422)
  fix(channels): offer only Copy link in a not-joined preview's sidebar actions (#2425)
  test: scope row menu placement checks to active section rows (#2493)
  feat(relay): detach channel windows to a point in history (#2042)
  feat(identity): decide a missing backup choice from community membership (#2378)
  Offer Builderlab decisions in FI builds (#2227)
  feat(inbox): preview recent Inbox activity when hovering the sidebar row (#2347)
  Add collapsible Solo and Team sidebar sections (#2296)
  fix(codex): open long Codex transcripts a page of items at a time (#2259)
  Keep Solo model and effort choices per chat (#2342)
  feat(sidebar): smooth channel reordering with bounded motion (#2108)
  Connect legacy agents from DMs and channel mentions (#2423)
  ...
michaelneale added a commit that referenced this pull request Nov 4, 2026
* origin/main: (31 commits)
  test: fix invitation and coordination checks on main (#2517)
  perf(search): name searched people from the profile search response (#2353)
  Use the merge queue for pull requests that require it (#2452)
  fix(browser): load scheme-less address input over https, falling back to http (#2467)
  fix(identity): stop one-click key unlinks and show the linked backed-up key (#2486)
  fix(test): observe coordination transition events (#2297)
  fix(profiles): keep the next view's profile reads through a shrink (#2395)
  fix(channels): show Add and Send message errors above the Manage members list (#2421)
  fix(threads): keep reply hooks off agent activity bubbles (#2422)
  fix(channels): offer only Copy link in a not-joined preview's sidebar actions (#2425)
  test: scope row menu placement checks to active section rows (#2493)
  feat(relay): detach channel windows to a point in history (#2042)
  feat(identity): decide a missing backup choice from community membership (#2378)
  Offer Builderlab decisions in FI builds (#2227)
  feat(inbox): preview recent Inbox activity when hovering the sidebar row (#2347)
  Add collapsible Solo and Team sidebar sections (#2296)
  fix(codex): open long Codex transcripts a page of items at a time (#2259)
  Keep Solo model and effort choices per chat (#2342)
  feat(sidebar): smooth channel reordering with bounded motion (#2108)
  Connect legacy agents from DMs and channel mentions (#2423)
  ...

Signed-off-by: Michael Neale <[email protected]>
cheng-block added a commit to cheng-block/buzz-app that referenced this pull request Nov 5, 2026
…punctuation

* upstream/main: (78 commits)
  fix(plugins): read Square HTTPS sources with the Block SSH agent (block#2465)
  feat(plugins): let agents request plugin changes for owner review (block#2280)
  fix(messages): keep the hover toolbar while its menu is open (block#2439)
  feat(workflows): suggest channel members for @ in Send Message text (block#2309)
  AIDA-2344: Exclude muted channels from Dock (block#2313)
  feat(search): add slack-style message search operators on desktop (block#2463)
  test: fix invitation and coordination checks on main (block#2517)
  perf(search): name searched people from the profile search response (block#2353)
  Use the merge queue for pull requests that require it (block#2452)
  fix(browser): load scheme-less address input over https, falling back to http (block#2467)
  fix(identity): stop one-click key unlinks and show the linked backed-up key (block#2486)
  fix(test): observe coordination transition events (block#2297)
  fix(profiles): keep the next view's profile reads through a shrink (block#2395)
  fix(channels): show Add and Send message errors above the Manage members list (block#2421)
  fix(threads): keep reply hooks off agent activity bubbles (block#2422)
  fix(channels): offer only Copy link in a not-joined preview's sidebar actions (block#2425)
  test: scope row menu placement checks to active section rows (block#2493)
  feat(relay): detach channel windows to a point in history (block#2042)
  feat(identity): decide a missing backup choice from community membership (block#2378)
  Offer Builderlab decisions in FI builds (block#2227)
  ...

Signed-off-by: Cheng Peng <[email protected]>

# Conflicts:
#	docs/buzz-help.md
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.

2 participants