Skip to content

[macOS 26.3] Export panics on NULL +[NSSavePanel savePanel] before rendering — editor freezes, GUI export impossible (0.5.9) #2163

Description

@maximilianmandel

Description

Clicking Export in the Studio editor immediately panics the main thread and freezes the entire app. The panic is:

[2026-08-29T15:54:28.580760+00:00] pid=96459 thread='main' at objc2-app-kit-0.3.1/src/generated/NSSavePanel.rs:103:5: unexpected NULL returned from +[NSSavePanel savePanel]
   7: objc2::__macro_helpers::retain_semantics::none_fail
   8: rfd::backend::macos::file_dialog::panel_ffi::Panel::build_save_file
   9: rfd::backend::macos::modal_future::ModalFuture<R,D>::new::{{closure}}
  10: rfd::file_dialog::AsyncFileDialog::save_file
  12: tauri_runtime_wry::handle_user_message

100% reproducible on this machine (3/3 attempts across 2 app restarts, incl. a fresh process). Because export_video_to_file_inner shows the save dialog before rendering, export is completely impossible from the GUI — the app must be force-killed each time.

Reproduction

  1. Record anything in Studio mode (happens with an 18-min window recording, but length seems irrelevant)
  2. Click Export in the editor
  3. App freezes; panics.log shows the NSSavePanel NULL panic

Environment

  • Cap 0.5.9 (Homebrew cask, bundle untouched since install — mtime matches release build)
  • macOS 26.3 (Tahoe, Darwin 25.3.0), MacBook Air M4, arm64

Diagnostics already done

  • Recording itself is flawless — all segments close cleanly, data intact.
  • This is not the post-auto-update signature mismatch from [bug] [macOS] NSOpenPanel openPanel returns NULL tauri-apps/tauri#13047: the bundle on disk was never modified after launch, and codesign -v --deep --strict passes.
  • The binary is single-arch arm64 (not universal) and already carries com.apple.security.cs.allow-jit + allow-unsigned-executable-memory, i.e. the workarounds discussed in the tauri issue don't apply/help.
  • macOS's panel XPC service (com.apple.appkit.xpc.openAndSavePanelService) is healthy on the machine — QuickTime Player used it successfully minutes after Cap's panic (verified in unified log). At Cap's panic moment the service is never even spawned for Cap's process: AppKit returns nil from +[NSSavePanel savePanel] before any XPC activity.
  • Unified log shows no ViewBridge/sandbox/codesign denials for Cap at panic time.

Workaround

cap-cli export (bundled in Cap.app/Contents/MacOS) renders the same project headlessly without issue — the bug is purely the GUI save-panel path.

Suggested fix

Two layers:

  1. Don't let a nil panel take down the app. rfd unconditionally unwraps +[NSSavePanel savePanel]; anything that makes AppKit return nil (this bug, tauri#13047's update case, remote sessions on Tahoe per reports there) becomes a main-thread panic and a frozen editor. Wrapping the dialog request so failure surfaces as an error/None instead would turn a hang into a handled case.
  2. Fall back to a default save location when the dialog can't be shown (e.g. ~/Desktop or the custom path requested in [Feature Request]: Separate custom storage paths for Projects, Videos, and Screenshots (Crucial for Local/Desktop Licenses) #1857), so export still works even when AppKit misbehaves. Since the render happens after path selection anyway, falling back costs nothing.

Happy to test patches — the repro is deterministic on this machine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions