Repository navigation
macOS: crash on launch — null ToolTipText in TrayIcon.Attach() #30
Description
PattN macOS: crash on launch — null ToolTipText in Avalonia TrayIcon.Attach()
خلاصه فارسی (TL;DR)
روی macOS جدید (27.0.1 / build 26A434، Apple Silicon) اپ PattN هنگام اجرا کرش میکند و
هیچ پنجرهای باز نمیشود. علت: در App.axaml خط ۴۰ برای TrayIcon مقدار
ToolTipText="{Binding RunningServerToolTipText}" ست شده، ولی آیکون تری در
App.Initialize() ساخته میشود، یعنی قبل از اینکه DataContext ست شود؛ در نتیجه مقدار
null به SetToolTipText میرسد و Avalonia 12.1.x آن را بدون چک null به
UTF8Encoding.GetByteCount میدهد → ArgumentNullException → abort().
این مشکل در هر ۴ ریلیز فعلی (P26, P27, P28, P29) وجود دارد.
راهحل پیشنهادی: یک FallbackValue غیر-null برای binding، یا ست کردن ToolTipText
ثابت، یا ساختن tray icon بعد از آماده شدن ViewModel.
Environment
- OS: macOS 27.0.1 (build 26A434), arm64 (Apple Silicon)
- PattN: 7.25.2-P29, asset
PattN-macos-arm64.dmg - Also reproduced on: P28 (7.25.2-P28), P27, P26 as shipped — all four current releases
contain the same binding (verified by readingApp.axamlat each tag) - Avalonia.Desktop: 12.1.3 (my-releases); 12.1.2 in P26/P27/P28
- Signature: adhoc / TeamIdentifier not set (not notarized), launched without quarantine
- Launch method: both
open -a /Applications/PattN.appand running
/Applications/PattN.app/Contents/MacOS/PattNdirectly → identical crash
Steps to reproduce
- Download
PattN-macos-arm64.dmgfrom release 7.25.2-P29 and install PattN.app. - Launch PattN.app.
- Expected: main window appears.
Actual: process aborts within ~1s, no window at all, every launch.
Actual result
Unhandled managed exception; process aborts (SIGABRT). Captured on stderr when the
binary is run from a terminal:
Unhandled exception. System.ArgumentNullException: ArgumentNull_Generic Arg_ParamName_Name, chars
at System.Text.UTF8Encoding.GetByteCount(String chars)
at Avalonia.Native.Interop.Impl.__MicroComIAvnTrayIconProxy.SetToolTipText(String text)
at Avalonia.Native.TrayIconImpl.SetToolTipText(String text)
at Avalonia.Controls.TrayIcon.Attach()
at Avalonia.Controls.TrayIcon.AttachIcons(IEnumerable`1 icons)
at Avalonia.Controls.TrayIcon.<>c.<.cctor>b__4_0(AvaloniaPropertyChangedEventArgs`1 args)
at Avalonia.Reactive.AnonymousObserver`1.OnNext(T value)
at Avalonia.Reactive.LightweightObservableBase`1.PublishNext(T value)
at Avalonia.Reactive.LightweightSubject`1.OnNext(T value)
at Avalonia.AvaloniaProperty`1.NotifyChanged(AvaloniaPropertyChangedEventArgs`1 e)
at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaProperty`1 property, ...)
at Avalonia.PropertyStore.EffectiveValue`1.NotifyValueChanged(ValueStore owner, ...)
at Avalonia.PropertyStore.ValueStore.SetValue[T](StyledProperty`1 property, ...)
at Avalonia.AvaloniaObject.SetValue[T](StyledProperty`1 property, T value, BindingPriority priority)
at Avalonia.Controls.TrayIcon.SetIcons(Application o, TrayIcons trayIcons)
at v2rayN.Desktop.App.!XamlIlPopulate(IServiceProvider, App) in App.axaml:line 79
at v2rayN.Desktop.App.!XamlIlPopulateTrampoline(App)
at v2rayN.Desktop.App.Initialize() in App.axaml.cs:line 10
at Avalonia.AppBuilder.SetupUnsafe()
at Avalonia.AppBuilder.Setup()
at Avalonia.AppBuilder.SetupWithLifetime(IApplicationLifetime lifetime)
at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(...)
at v2rayN.Desktop.Program.Main(String[] args) in Program.cs:line 22
Crash report also written to ~/Library/Logs/DiagnosticReports/PattN-2026-10-02-132415.ips:
exception: EXC_CRASH / SIGABRT, termination: Abort trap: 6,
faulting frames: abort → TerminateProcess → DispatchManagedException → IL_Throw.
Root cause
v2rayN/v2rayN.Desktop/App.axaml line 40:
<TrayIcon
Command="{Binding NotifyLeftClickCmd}"
Icon="/Assets/NotifyIcon1.ico"
ToolTipText="{Binding RunningServerToolTipText}">The <TrayIcon.Icons> block is part of the Application XAML, so the tray icon is
attached during App.Initialize() — before any DataContext / StatusBarViewModel
exists. The binding therefore evaluates to null, and Avalonia.Controls.TrayIcon.Attach()
passes that null straight to TrayIconImpl.SetToolTipText().
Avalonia 12.1.x marshals the argument into UTF8Encoding.GetByteCount(string), which
throws ArgumentNullException on null → unhandled → abort().
Because this happens during application initialization, it is deterministic on every
launch (not a race), and it explains why no window is ever shown.
Suggested fixes (any one is enough)
- Give the binding a non-null fallback:
ToolTipText="{Binding RunningServerToolTipText, FallbackValue=PattN}" - Or set a static tooltip:
ToolTipText="PattN"and update it later from code when the
view-model is ready. - Or move tray-icon creation out of
App.axamland attach it after the main window /
StatusBarViewModelDataContext is established. - Upstream/Avalonia-side: treat
nullas""inTrayIconImpl.SetToolTipText(defensive
null handling) — this is arguably the real bug in Avalonia's macOS backend. - If pinning Avalonia: verify whether 12.1.2 tolerated a null tooltip; if so, P26–P28 may
only crash because the binding is present, and the same XAML guard fixes all of them.
Notes
- This may be specific to very new macOS (26A434); I could not find any release that
launches successfully here, so please confirm whether the macOS build is expected to
work on macOS 27. - Workaround I used meanwhile: the bundled patched core at
PattN.app/Contents/MacOS/bin/xray/xray(Xray 26.9.27) runs fine standalone with a
hand-written config (verified withxray -test, including thefinalmaskfragment
block andfingerprint=unsafe+cipherSuites). So only the GUI is affected, not the core.
Activity
[-][Bug]: GUI crash on macOS[/-][+]macOS: crash on launch — null ToolTipText in TrayIcon.Attach()[/+]MiladGolchinpour commentedon Oct 2, 2026
Fixed in #27