Skip to content

Fix macOS 27 crash opening browser panel (zero-size SF Symbol rasterization) - #5842

Closed
matheustimbo wants to merge 2 commits into
manaflow-ai:mainfrom
matheustimbo:fix/macos27-browser-toolbar-symbol-crash
Closed

matheustimbo wants to merge 2 commits into
manaflow-ai:mainfrom
matheustimbo:fix/macos27-browser-toolbar-symbol-crash

Conversation

@matheustimbo

@matheustimbo matheustimbo commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #5841 — follow-up to #5670. The same macOS 26+ zero-size SF Symbol rasterization crash still fires in the browser panel toolbar: cmd-clicking a terminal link (which opens the integrated browser) crashes cmux on macOS 27.0.

Root cause

Captured under lldb on macOS 27:

<CUINamedVectorGlyph: …> 'wrench.and.screwdriver' @2x, 11-points, Medium weight … Width=0; Height=0
*** Invalid parameter not satisfying: targetSizeInPoints.width>0 && targetSizeInPoints.height>0
objc_exception_throw
  -[CUINamedVectorGlyph _rasterizeImageUsingScaleFactor:forTargetSize:renderingMode:colorResolver:]
  … RenderBox RBSymbolUpdateTemplateImage
  … SwiftUI  _ShapeStyle_RenderedShape.renderVectorGlyph(…)
  … AppKit   -[NSView addSubview:] → _setDefaultKeyViewLoop → layoutSubtreeIfNeeded
  … cmux     Workspace.flushWorkspaceWindowLayouts()  (Workspace.swift:17295)

BrowserPanelView's toolbar sizes its SF Symbols with .font(.system(size:weight:)). When the panel's SwiftUI hosting view is added to the hierarchy during a layout follow-up, font metrics aren't resolved yet, so the symbols rasterize at 0×0 — which macOS 26+ rejects with an uncaught NSInvalidArgumentException, crashing the app. The captured glyph is wrench.and.screwdriver (the default dev-tools button), but all ~12 .font-sized toolbar symbols are exposed.

Fix

Adds an Image.cmuxSymbolPixelSize(_:weight:) helper that drives the symbol's raster size from an explicit frame via .resizable().scaledToFit() — the same approach merged for SidebarHelpMenuButton in #5670 — and applies it across the browser toolbar (navigation chevrons, reload/stop, screenshot camera, focus keyboard, react-grab cursor, dev-tools, profile, theme, import hint, secure lock badge). Visual output is unchanged.

Verification

Built with Xcode 27 (macOS 27 SDK) and run on macOS 27.0 (26A5353q): before the fix, cmd-clicking a link crashed within ~1s, every time; after the fix, the browser panel opens and the app stays up (verified by reproducing the exact cmd-click flow under an isolated tagged build).

Note

The .font(.system(size:))-on-symbol pattern exists in other panels app-wide; this PR fixes the browser toolbar (the reported crash). A broader sweep (or the reusable helper applied more widely) would harden the remaining surfaces — happy to follow up.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved icon sizing and rendering consistency across navigation controls, reload/stop, developer tools, profile, theme switcher, import hint, secure badge, screenshot, and focus features.
    • Prevented transient icon rasterization/display issues on recent macOS releases.
    • Preserved existing monochrome and flat appearance for affected toolbar and interface icons.
    • Ensured uniform pixel-aligned sizing for toolbar symbols to reduce visual glitches.

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

@matheustimbo is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b702dcef-de7b-4e8e-94c8-1a22b2bf35f8

📥 Commits

Reviewing files that changed from the base of the PR and between 8d93a74 and ad0af93.

📒 Files selected for processing (3)
  • Sources/ContentView.swift
  • Sources/Panels/BrowserPanelView.swift
  • Sources/RenderableSystemSymbol.swift
💤 Files with no reviewable changes (1)
  • Sources/Panels/BrowserPanelView.swift

📝 Walkthrough

Walkthrough

Adds Image.cmuxSymbolPixelSize(_:weight:) to size SF Symbols via an explicit centered frame and replaces font-based SF Symbol sizing with this helper across BrowserPanelView toolbar icons and one ContentView usage.

Changes

Browser Toolbar SF Symbol Sizing

Layer / File(s) Summary
SF Symbol sizing helper
Sources/RenderableSystemSymbol.swift
Adds Image.cmuxSymbolPixelSize(_:weight:) which applies .resizable().scaledToFit(), sets fontWeight, and enforces a centered square .frame(width:height:) to prevent zero-size rasterization.
Navigation toolbar icon migration
Sources/Panels/BrowserPanelView.swift
Replaces .font(.system(...)) sizing with cmuxSymbolPixelSize(...) for back, forward, and reload/stop omnibar icons.
Action and status icon migration
Sources/Panels/BrowserPanelView.swift
Migrates screenshot, keyboard/focus, React Grab, dev tools, profile, theme, import-hint chip, and secure-badge lock icons to use cmuxSymbolPixelSize(...), preserving .symbolRenderingMode(.monochrome) and .cmuxFlatSymbolColorRendering() modifiers.
ContentView symbol sizing update
Sources/ContentView.swift
Replaces previous resizable/font/frame modifier chain with cmuxSymbolPixelSize(iconSize, weight: .medium) while keeping rendering mode and foreground styling unchanged.

Sequence Diagram(s)

sequenceDiagram
  participant ViewUsingImage
  participant Image.cmuxSymbolPixelSize
  participant SwiftUIRenderer
  ViewUsingImage->>Image.cmuxSymbolPixelSize: request symbol with size & weight
  Image.cmuxSymbolPixelSize->>SwiftUIRenderer: provide resizable symbol with explicit frame
  SwiftUIRenderer->>ViewUsingImage: render non-zero-rasterized symbol
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

  • manaflow-ai/cmux#5670: Fixes the same SF Symbol 0×0 rasterization crash on macOS 26+/27 in ContentView.swift using explicit .frame() sizing.
  • manaflow-ai/cmux#5464: Also modifies BrowserPanelView toolbar icon sizing; overlaps on icon sizing choices and call sites.
  • manaflow-ai/cmux#5037: Related changes to Sources/RenderableSystemSymbol.swift utilities that interact with symbol rendering helpers.

Poem

🐰 I hop and tweak each tiny glyph,

Frame them square and keep them stiff,
No zero pixels in my lair,
Toolbar icons breathe easy air,
Hooray — the symbols sit just right.


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Source Artifacts ❌ Error PR adds 25 .claude/ files (scratch directory), 3 .greptile/, 1 .cursor/, and 1 .coderabbit file—all explicitly prohibited artifact directories per source-control-artifacts.md rule. Remove .claude/, .greptile/, .cursor/, and .coderabbit entries from diff, or add narrow .gitignore patterns if intentionally managing these tool configs.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (19 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing a macOS 27 crash caused by zero-size SF Symbol rasterization in the browser panel toolbar.
Description check ✅ Passed The description covers all required sections: summary with what changed and why, root cause analysis, fix explanation, and verification steps. Testing section confirms manual testing on macOS 27.
Linked Issues check ✅ Passed The code changes fully address issue #5841: implementing the cmuxSymbolPixelSize helper and applying it across the browser toolbar symbols to prevent zero-size rasterization crashes.
Out of Scope Changes check ✅ Passed All changes are scoped to the browser toolbar symbol rendering fix. No unrelated modifications to other panels or unrelated features are present.
Cmux Swift Actor Isolation ✅ Passed PR adds only a SwiftUI Image extension method (cmuxSymbolPixelSize) that safely composes View modifiers without MainActor dependencies, consistent with existing View extensions and SwiftUI patterns.
Cmux Swift Blocking Runtime ✅ Passed PR introduces no blocking or timing-based synchronization. Changes are purely UI rendering: adds Image.cmuxSymbolPixelSize extension and replaces .font() sizing with explicit frame sizing on SF Sym...
Cmux Expensive Synchronous Load ✅ Passed PR adds Image.cmuxSymbolPixelSize() helper for SF Symbol rendering, not expensive sync loaders; no RestorableAgentSessionIndex or similar disk/sysctl operations added to interactive paths.
Cmux Cache Substitution Correctness ✅ Passed PR adds a UI symbol-rendering modifier and updates toolbar symbol rendering; contains no cache substitution in persistence, history, undo, or snapshot paths. The check is not applicable.
Cmux No Hacky Sleeps ✅ Passed Check not applicable: PR modifies only Swift files (.swift), which are explicitly out of scope per runtime-no-hacky-sleeps.md (scope: TypeScript, JavaScript, shell, non-Swift build/runtime scripts).
Cmux Algorithmic Complexity ✅ Passed PR applies fixed O(1) modifier chains to individual toolbar buttons; no collection scans, rescans, sorts, filters, or other complexity violations detected.
Cmux Swift Concurrency ✅ Passed PR adds synchronous SwiftUI Image modifier (cmuxSymbolPixelSize) with no async/await, Dispatch queues, Combine state, or fire-and-forget Tasks—all concurrency modernization requirements met.
Cmux Swift @Concurrent ✅ Passed The PR adds only synchronous UI helper code (Image.cmuxSymbolPixelSize) and uses it in view composition—no async functions, @concurrent annotations, or actor isolation changes. No violations of Swi...
Cmux Swift File And Package Boundaries ✅ Passed PR adds 20-line Image.cmuxSymbolPixelSize() helper to small RenderableSystemSymbol.swift (78 lines total), with only +11/−11 net to BrowserPanelView (7737 lines, already oversized) and +1/−9 to Con...
Cmux Swift Logging ✅ Passed No logging violations found. The three modified files contain no new print/debugPrint/dump/NSLog calls. Pre-existing DEBUG-guarded NSLog in ContentView is allowed per rules.
Cmux User-Facing Error Privacy ✅ Passed PR contains only internal SF Symbol rendering refactoring with no new user-facing error messages, alerts, or sensitive data exposure. The new cmuxSymbolPixelSize extension is technical code with de...
Cmux Full Internationalization ✅ Passed PR adds RenderableSystemSymbol.swift with only technical code (SF Symbol names) and updates BrowserPanelView/ContentView; all user-facing strings already use String(localized:) with complete transl...
Cmux Swiftui State Layout ✅ Passed PR contains only pure view modifier changes for SF Symbol sizing (cmuxSymbolPixelSize), with no new state/observable declarations, GeometryReader measurement changes, lazy subtree store references,...
Cmux Architecture Rethink ✅ Passed PR implements a small correctness fix with clear owner (Image extension) and documented invariant (frame size positive across layout passes); pure view modifier addressing macOS 26+ zero-size SF Sy...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds Image.cmuxSymbolPixelSize rendering helper and applies it to existing toolbar buttons in BrowserPanelView and ContentView. No new standalone NSWindow, NSPanel, NSWindowController, or SwiftU...
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the macOS 26+ / macOS 27 crash that fires when the browser panel toolbar is first laid out: SF Symbols sized via .font(.system(size:)) can rasterize at 0×0 before font metrics resolve, and AppKit 26+ rejects a zero raster with an uncaught NSInvalidArgumentException. The fix introduces a shared Image.cmuxSymbolPixelSize(_:weight:) extension (in RenderableSystemSymbol.swift) that drives raster size from an explicit fixed frame, identical in spirit to the #5670 fix applied to SidebarHelpMenuButton.

  • Adds cmuxSymbolPixelSize to the shared RenderableSystemSymbol.swift with a clear doc-comment linking to the original crash and both issue numbers.
  • Applies the helper to all ~10 SF Symbol images in the browser panel toolbar and refactors SidebarHelpMenuButton in ContentView.swift to use the same abstraction, removing the now-redundant inline comment.

Confidence Score: 5/5

Safe to merge — the change is a targeted, mechanically straightforward modifier swap with no new state, no layout mutation during rendering, and no behavioral changes beyond eliminating the zero-size rasterization path.

Every changed site is a pure view-modifier substitution: .font(.system(size:weight:)) is replaced by cmuxSymbolPixelSize, which chains .resizable() / .scaledToFit() / .fontWeight / .frame — the same four steps that #5670 already validated for SidebarHelpMenuButton. The new shared helper is correctly placed in RenderableSystemSymbol.swift, its doc-comment captures the full rationale, and the downstream modifier order (rendering-mode environment values applied after the fixed frame) is safe because SwiftUI propagates them into framed child views. No actor isolation, blocking, logging, or i18n concerns are introduced.

No files require special attention. The PR author's note that the .font(.system(size:)) pattern exists in other panels app-wide is an acknowledged follow-up item, not a concern in the current diff.

Important Files Changed

Filename Overview
Sources/RenderableSystemSymbol.swift Adds Image.cmuxSymbolPixelSize(_:weight:) extension — a well-documented shared helper that replaces font-metric sizing with an explicit fixed frame, eliminating the zero-size rasterization crash on macOS 26+. Helper is correctly placed in a module-level shared file.
Sources/Panels/BrowserPanelView.swift Replaces .font(.system(size:weight:)) with cmuxSymbolPixelSize across all ~10 SF Symbol toolbar images (chevrons, reload, screenshot, focus, react-grab, dev-tools, profile, theme, import hint, secure badge). Modifier ordering is correct since SwiftUI propagates rendering-mode environment values downward through the framed child view.
Sources/ContentView.swift Refactors SidebarHelpMenuButton to use the new shared cmuxSymbolPixelSize helper, removing the inline four-step pattern and its explanatory comment (now captured in the helper's doc-comment). Functionally equivalent.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Image(systemName:)"] --> B["cmuxSymbolPixelSize(size, weight)"]
    B --> B1[".resizable()"]
    B1 --> B2[".scaledToFit()"]
    B2 --> B3[".fontWeight(weight)"]
    B3 --> B4[".frame(size × size)"]
    B4 --> C[".symbolRenderingMode(.monochrome) ①"]
    C --> D[".cmuxFlatSymbolColorRendering() ①"]
    D --> E[".foregroundStyle(color)"]
    E --> F[".frame(buttonSize × buttonSize) — hit target"]

    subgraph macOS_26_path["macOS 26+ layout pass"]
        G["font metrics not yet resolved"] --> H["⚠ .font() rasterizes at 0×0"]
        H --> I["NSInvalidArgumentException → crash"]
        J["explicit .frame() rasterizes at size × size"] --> K["✅ always positive — no crash"]
    end

    B4 -.->|fixes| K
    A -.->|old path| H

    note1["① env-propagated: correctly reaches Image inside fixed frame"]
Loading

Reviews (3): Last reviewed commit: "Move cmuxSymbolPixelSize to a shared fil..." | Re-trigger Greptile

Comment thread Sources/Panels/BrowserPanelView.swift Outdated
Comment on lines +137 to +155
extension Image {
/// Sizes an SF Symbol from an explicit frame rather than font metrics.
///
/// A `.font(.system(size:))`-sized symbol can rasterize at 0×0 during a
/// transient layout pass (e.g. while a panel's hosting view is first added
/// to the hierarchy, before font metrics resolve). macOS 26+ rejects a
/// zero raster size with an uncaught `NSInvalidArgumentException`
/// (`targetSizeInPoints.width>0 && targetSizeInPoints.height>0`), which
/// AppKit turns into a hard crash. Driving the raster size from a fixed
/// frame keeps it positive across every layout pass. Mirrors the fix in
/// `SidebarHelpMenuButton` (#5670).
func cmuxSymbolPixelSize(_ size: CGFloat, weight: Font.Weight = .regular) -> some View {
self
.resizable()
.scaledToFit()
.fontWeight(weight)
.frame(width: size, height: size, alignment: .center)
}
}

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.

P2 Module-visible helper defined in a panel-specific file

cmuxSymbolPixelSize is internal (no access modifier), making it siloed in BrowserPanelView.swift but technically visible across the whole module. SidebarHelpMenuButton in ContentView.swift (lines 14554–14566) already inlines the exact same four-step pattern (resizable / scaledToFit / fontWeight / frame) without knowing this helper exists, which is a direct consequence of the discoverability gap. The PR description explicitly says the .font(.system(size:)) pattern exists in other panels app-wide, so having the canonical helper live in a panel view rather than a shared Image+CMux.swift or ViewModifiers+SymbolSize.swift file means future adopters will keep re-inventing it inline. Moving it to a shared utilities file would also let you retroactively update SidebarHelpMenuButton to use the same abstraction.

Rule Used: Flag Swift changes that add too much unrelated res... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call — addressed in the follow-up commit: moved cmuxSymbolPixelSize to the shared RenderableSystemSymbol.swift and updated SidebarHelpMenuButton to use it, removing the duplicated inline pattern. No behavior change.

…zation)

Follow-up to manaflow-ai#5670. The browser panel toolbar sized its SF Symbols with
`.font(.system(size:weight:))`. When the panel's SwiftUI hosting view is
added to the hierarchy during a layout follow-up
(`Workspace.flushWorkspaceWindowLayouts`), font metrics aren't resolved yet,
so the symbols rasterize at 0×0 — which macOS 26+ rejects with an uncaught
`NSInvalidArgumentException` ("targetSizeInPoints.width>0 &&
targetSizeInPoints.height>0"), crashing the app the moment a link is
cmd-clicked (which opens the browser). Captured glyph: `wrench.and.screwdriver`
(the default dev-tools button), but every `.font`-sized toolbar symbol is
exposed.

Add an `Image.cmuxSymbolPixelSize(_:weight:)` helper that drives the raster
size from an explicit frame via `.resizable().scaledToFit()` (same approach as
the SidebarHelpMenuButton fix in manaflow-ai#5670), and apply it across the browser
toolbar: navigation chevrons, reload/stop, screenshot camera, focus keyboard,
react-grab cursor, dev-tools, profile, theme, import hint, and the secure
lock badge. Visual output is unchanged.

Fixes manaflow-ai#5841
@matheustimbo
matheustimbo force-pushed the fix/macos27-browser-toolbar-symbol-crash branch from b9693fe to 8d93a74 Compare June 10, 2026 22:41
…tton

Addresses review feedback on the helper's discoverability: `cmuxSymbolPixelSize`
lived in `BrowserPanelView.swift` (module-visible but siloed) while
`SidebarHelpMenuButton` re-implemented the same four-step
`resizable/scaledToFit/fontWeight/frame` pattern inline.

Move the helper to the shared `RenderableSystemSymbol.swift` and have both the
browser toolbar and `SidebarHelpMenuButton` use it, removing the duplicated
inline pattern. No behavior change.
@matheustimbo

Copy link
Copy Markdown
Contributor Author

@austinywang follow-up to #5670 — same macOS 27 zero-size SF Symbol crash class, this time in the browser panel toolbar (reproduced + fixed; details in the description). Review bots are green; the Vercel checks are just the fork deploy-authorization gate (changes are macOS-app only, no web). Could you kick off CI / take a look when you have a moment? 🙏

hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request Jun 11, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator

Thanks for this! The macOS 27 zero-size SF Symbol crash in the browser panel landed on main in #6728. You opened this first, so you got there first. Closing since main covers it now.

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.

Crash on macOS 27 when cmd-clicking a link (browser toolbar SF Symbol rasterized at 0×0)

2 participants