Skip to content

fix(gpui): load older thread replies after the list releases its state - #91

Merged
thebrandonlucas merged 3 commits into
fix/gpui-read-buzz-app-identityfrom
fix/gpui-thread-scroll-crash
Oct 29, 2026
Merged

thebrandonlucas merged 3 commits into
fix/gpui-read-buzz-app-identityfrom
fix/gpui-thread-scroll-crash

Conversation

@thebrandonlucas

@thebrandonlucas thebrandonlucas commented Oct 28, 2026 •

Copy link
Copy Markdown

Problem

Scrolling up in a thread that has older replies aborts the app (#89):

gpui-pre-0.3.8/src/elements/list.rs:647:16: RefCell already borrowed
panic in a function that cannot unwind ... gpui_macos::window::handle_view_event

GPUI calls a list's scroll handler from ListState::scroll, while it holds the list's RefCell borrowed mutably. The thread panel's handler called load_older, which calls pause_following_tail and logical_scroll_top on the same list.

Change

The handler runs load_older with cx.defer, after GPUI releases the borrow. The other scroll handlers (channel, emoji picker, avatar editor) do not touch their list's state, so they are unchanged.

Validation

  • cargo clippy -p buzz-gpui --features voltage-sandbox --all-targets -D warnings: passes.
  • I did not reproduce the crash again with the fix. To check: open a thread with more than one page of replies and scroll to the top.

Fixes #89 · Linear DEV-2981

Summary by CodeRabbit

  • Bug Fixes
    • Improved older-reply loading when scrolling, helping replies load reliably without disrupting the list.

GPUI calls a list's scroll handler while it holds the list's state
borrowed. The thread panel's handler called load_older, which reads
and changes that state, so scrolling up in a thread with older replies
panicked with "RefCell already borrowed" and aborted the app. Run
load_older with cx.defer instead.

Fixes #89
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 4c9bc32 and cf26705.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between b1f7aad and 4c9bc32.

Files selected for processing: 1
  • apps/buzz-gpui/crates/app/src/ui/thread.rs

Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

Walkthrough

The thread panel’s near-top scroll handler now defers load_older() through cx.defer instead of calling it synchronously inside the list-state callback.

Changes: Thread older replies

Layer / File(s) Summary
Deferred older-reply loading
apps/buzz-gpui/crates/app/src/ui/thread.rs
The near-top scroll handler clones its weak panel reference and defers load_older() until GPUI releases the list state.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • voltagecloud/buzz#89 describes the same RefCell borrow panic when loading older replies from the thread scroll handler. This change defers that call.

Suggested labels: human review wanted

Suggested reviewers: tee8z

Merge Risk: Minimal · previous review 4c9bc

The reported scroll crash is addressed without changing older-reply loading behavior.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: deferring older thread reply loading until the GPUI list releases its state.
Linked Issues check Passed Issue #89 requires deferring thread-panel load_older until GPUI releases the list-state borrow. In apps/buzz-gpui/crates/app/src/ui/thread.rs, the scroll handler clones the weak entity and calls `…
Out of Scope Changes check Passed The reviewed diff changes only the thread-panel older-replies scroll handler. The change directly addresses issue #89 and does not add unrelated behavior.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Full details: Linked Issues check

Explanation

Issue #89 requires deferring thread-panel load_older until GPUI releases the list-state borrow. In apps/buzz-gpui/crates/app/src/ui/thread.rs, the scroll handler clones the weak entity and calls load_older inside cx.defer. The reported validation also states that the targeted clippy command passes.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 1 files.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@thebrandonlucas
thebrandonlucas marked this pull request as ready for review October 29, 2026 13:24
@thebrandonlucas
thebrandonlucas changed the base branch from main to fix/gpui-read-buzz-app-identity October 29, 2026 13:25
@thebrandonlucas
thebrandonlucas added this pull request to stack #92 October 29, 2026 13:26
tee8z
tee8z previously approved these changes Oct 29, 2026

@tee8z tee8z left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving.

  • The cause checks out. load_older calls capture_older_anchor, which calls pause_following_tail and logical_scroll_top on the same ListState that GPUI holds borrowed while it runs the scroll handler. cx.defer is the minimal fix.
  • I checked the other set_scroll_handler users. Channel's load_near_top only reads the timeline model and calls model.load_older(). The emoji picker only sets its own fields. Neither touches its list, so leaving them unchanged is right.
  • The keyboard path (thread.rs, logical_scroll_top() < LOAD_OLDER_WITHIN → load_older()) runs outside the handler, so the fix doesn't affect it.
  • A burst of scroll events can queue several deferred load_older calls. That's harmless: ThreadState::start returns early while self.run.is_some(), so only one page fetch runs.

Not verified here: a crash repro with the fix. The PR's step (open a thread with more than one page of replies, scroll to the top) is the human check.

Minimalism 10 · elegance 9 · correctness 9.

@tee8z tee8z left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-approving. The earlier approval was dismissed by the stale-review automation when the stack's merge commits propagated #90's fix (17:39:52Z); this PR's own diff is unchanged from what I reviewed. Findings and gates from the previous review stand.

@thebrandonlucas
thebrandonlucas merged commit 6706fa6 into main Oct 29, 2026
40 checks passed
@thebrandonlucas
thebrandonlucas deleted the fix/gpui-thread-scroll-crash branch October 29, 2026 18:57
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.

Buzz GPUI app crashes (RefCell already borrowed) when scrolling up in a thread with older replies

2 participants