Repository navigation
fix(sidebar): guard every worktree sort against undefined displayName (crash 99657ab1) - #9315
Merged
Merged
Conversation
Contributor
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a shared 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… (crash 99657ab1) Worktree.displayName is typed non-optional but arrives undefined at runtime for persisted/discovered worktrees (crash 99657ab1). PR #8683 fixed the kanban board; this extends the same guard to the five other sort sites that share those worktree objects — including the Cmd+J switcher (order-empty-query-worktrees) — via one shared compareWorktreeDisplayName helper in lib/. Behavior-neutral when names are present; a missing name now sorts as '' instead of throwing. Co-authored-by: Orca <help@stably.ai>
nwparker
force-pushed
the
nwparker/harden-worktree-displayname-sort
branch
from
July 18, 2026 08:51
b3e4f67 to
2360133
Compare
… rule Anchors the existing 'document the why, briefly' rule with a concrete before/after (the worktree-displayName guard) so agents stop dumping the crash id, mechanism, file location, and every call site into a comment. Co-authored-by: Orca <help@stably.ai>
6 tasks
enrick-dev
pushed a commit
to enrick-dev/orca
that referenced
this pull request
Oct 15, 2026
… (crash 99657ab1) (stablyai#9315) * fix(sidebar): guard every worktree sort against undefined displayName (crash 99657ab1) Worktree.displayName is typed non-optional but arrives undefined at runtime for persisted/discovered worktrees (crash 99657ab1). PR stablyai#8683 fixed the kanban board; this extends the same guard to the five other sort sites that share those worktree objects — including the Cmd+J switcher (order-empty-query-worktrees) — via one shared compareWorktreeDisplayName helper in lib/. Behavior-neutral when names are present; a missing name now sorts as '' instead of throwing. Co-authored-by: Orca <help@stably.ai> * docs(agents): add over-commenting anti-pattern example to the comment rule Anchors the existing 'document the why, briefly' rule with a concrete before/after (the worktree-displayName guard) so agents stop dumping the crash id, mechanism, file location, and every call site into a comment. Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Extends the crash-99657ab1 guard —
TypeError: Cannot read properties of undefined (reading 'localeCompare')— to every worktree-sort site, not just the sidebar board.Worktree.displayNameis typedstring, but crash 99657ab1 proved it arrives undefined at runtime for persisted/discovered worktrees. PR #8683 fixed the sidebar kanban board. An adversarial review of this change found five other sort sites still calling barea.displayName.localeCompare(b.displayName)on the same worktree objects — including the Cmd+J quick switcher, a high-traffic surface where an undefined name would crash harder than the original report.This routes all raw-
Worktreesorts through one shared, guarded comparator.Change
src/renderer/src/lib/worktree-display-name-order.ts—compareWorktreeDisplayName(a, b)=(a.displayName ?? '').localeCompare(b.displayName ?? ''). Placed inlib/so every layer (sidebar, right-sidebar, Cmd+J, telemetry) shares one guard without a cross-feature import.components/sidebar/workspace-kanban-worktree-groups.ts(board — dedupes the local guard from fix(sidebar): guard kanban worktree sort against undefined displayName (crash 99657ab1) #8683)lib/order-empty-query-worktrees.ts(Cmd+J switcher)components/right-sidebar/folder-workspace-attached-worktrees.tscomponents/right-sidebar/parent-pr-checks-refresh.tscomponents/sidebar/add-repo-existing-workspaces-telemetry.tscomponents/sidebar/use-complete-git-repo-add.tsDeliberately out of scope (not raw
Worktree; only at risk if a builder copies an undefinedWorktree.displayName, and one lives in the main process which must not import a renderer helper):WorkspaceSpaceWorktree(status-bar/workspace-space-presentation.ts,main/workspace-space-analysis.ts),WorkspaceCleanupCandidate(workspace-cleanup/…), and the non-Worktree project-options / port-group sorts.CLEAR, UNDENIABLE fix evidence
Before (identical shape to the fixed kanban crash), e.g. the Cmd+J switcher:
After:
Call-site wiring tests reproduce the exact crash class (an undefined-
displayNameworktree inside the real production sort fns) and assert it no longer throws:npx tsc --noEmit -p config/tsconfig.tc.web.json→ exit 0oxlint(changed files) → clean ·oxfmt --check→ cleanELI5
The app sorts your worktrees by name in several places. Some worktrees show up before they've been given a name (name = "nothing"/undefined). Asking nothing to alphabetically compare itself throws an error and takes down whatever panel is sorting — the sidebar board (already fixed), and it turns out the Cmd+J switcher and a few other lists too. This teaches every one of those places the same safe trick — "treat a missing name as empty" — and moves that trick into a single shared helper so a future sort can't forget it.
Trade-offs / behavior changes
??only coalesces null/undefined, never''or other values). The only behavioral difference is the previously-crashing case: a worktree with a missing name now sorts as if its name were""(empty sorts first) instead of throwing.Adversarial review
displayNamein a sort) is captured by call-site wiring tests that fail without the guard and mirror the real crash 99657ab1.Worktreesort sites remained, including the Cmd+J switcher; I folded all of them in, relocated the comparator tolib/for correct layering, and added call-site wiring tests. Round 2 (fresh subagent): CLEAN — no blockers or majors — independently verified completeness (all 6 raw-Worktree sites guarded; remaining.localeComparesites are out-of-scope derived types), layering (no cycle, no main-process import), byte-identical ordering when names are present, correct nested-worktreepassing in parent-pr-checks, and that each wiring test fails if the guard is removed./perfskill, subagent): perf-neutral — no regression, no win. The kanban comparator is byte-identical to before (the local guard already had?? ''); the new coalesce affects only cold, non-per-frame sort paths.?? ''reuses an interned string literal (no allocation), samelocaleComparecall count, no new React subscriptions/effects.Closes the remaining unguarded instances of the crash-99657ab1 class.
Made with Orca 🐋