Description
A Wails v3 app on Linux that uses both a SystemTray and desktop notifications crashes with panic error: runtime error: index out of range [2] with length 2 from linuxSystemTray.run's signal-handling goroutine.
run() adds a single match for org.freedesktop.DBus.NameOwnerChanged so it can re-register the StatusNotifierItem when the watcher restarts, then routes signals through conn.Signal(sc). The handler indexes sig.Body[2] unconditionally:
// v3/pkg/application/systemtray_linux.go:417-419 (master)
// sig.Body has the args, which are [name old_owner new_owner]
if sig.Body[2] != "" {
s.register()
}
In godbus, conn.Signal(sc) delivers every signal the connection receives, not just the ones matching the per-channel rules. The systray opens dbus.SessionBus(), which returns a process-wide singleton connection — shared with anything else in the app that talks to the session bus. As soon as another part of the app subscribes to a 2-arg signal, it lands in the systray's channel and the unbounded index panics.
defer handlePanic() in the goroutine recovers, but the default panic handler (defaultPanicHandler → globalApplication.fatal) then exits the process — so the user sees the app die.
Same code is on master (systemtray_linux.go:418) and v3.0.0-alpha.78.
To Reproduce
Captured with this instrumentation in linuxSystemTray.run:
case sig := <-sc:
if sig == nil { return }
if len(sig.Body) < 3 {
fmt.Fprintf(os.Stderr,
"[dbg] short signal: name=%q path=%q sender=%q len=%d body=%#v\n",
sig.Name, sig.Path, sig.Sender, len(sig.Body), sig.Body)
}
if len(sig.Body) >= 3 && sig.Body[2] != "" { s.register() }
Output from a Wails v3 mail client running idle for ~2 minutes:
[dbg] short signal: name="org.freedesktop.Notifications.ActionInvoked" path="/org/freedesktop/Notifications" sender=":1.45" len=2 body=[]interface{}{0x3d, "default"}
[dbg] short signal: name="org.freedesktop.Notifications.NotificationClosed" path="/org/freedesktop/Notifications" sender=":1.45" len=2 body=[]interface{}{0x3d, 0x2}
[dbg] short signal: name="org.freedesktop.Notifications.NotificationClosed" path="/org/freedesktop/Notifications" sender=":1.45" len=2 body=[]interface{}{0x3e, 0x2}
[dbg] short signal: name="org.freedesktop.Notifications.NotificationClosed" path="/org/freedesktop/Notifications" sender=":1.45" len=2 body=[]interface{}{0x3c, 0x2}
[dbg] short signal: name="org.freedesktop.Notifications.NotificationClosed" path="/org/freedesktop/Notifications" sender=":1.45" len=2 body=[]interface{}{0x3f, 0x2}
org.freedesktop.Notifications.ActionInvoked(u, s) and NotificationClosed(u, u) both have 2-element bodies per the Desktop Notifications spec. The mail client subscribes to them on the session bus to know when its notifications are clicked or auto-dismissed; that subscription causes godbus to start delivering them to every registered Signal() channel, including the systray's.
Repro is therefore: a Wails v3 app that creates a SystemTray AND has any other code on the session bus subscribing to a 2-arg (or 0/1-arg) signal will eventually crash on the first such signal received after startup.
Expected behaviour
The signal-handling goroutine must filter on the signal name (and bounds-check the body) before indexing it. Anything other than org.freedesktop.DBus.NameOwnerChanged should be ignored.
case sig := <-sc:
if sig == nil { return }
if sig.Name != "org.freedesktop.DBus.NameOwnerChanged" { continue }
if len(sig.Body) >= 3 && sig.Body[2] != "" { s.register() }
Screenshots
No response
Attempted Fixes
The patch above stops the crash. Ready to PR.
System Details
Wails: v3.0.0-alpha.78 (also reproducible on master)
OS: Ubuntu 24.04 base (Linux Mint 22.x)
Kernel: Linux 6.17.0-20-generic
DE: Cinnamon on X11
dbus: 1.14.10-4ubuntu4.1
Go: go1.26.1 linux/amd64
Additional context
Original crash trace before instrumentation:
panic error: runtime error: index out of range [2] with length 2
runtime.panicBounds64
at runtime/panic.go:236
runtime.panicBounds
at runtime/asm_amd64.s:2129
github.com/wailsapp/wails/v3/pkg/application.(*linuxSystemTray).run.func1
at github.com/wailsapp/wails/v3/pkg/application/systemtray_linux.go:418
runtime.goexit
at runtime/asm_amd64.s:1771
Description
A Wails v3 app on Linux that uses both a
SystemTrayand desktop notifications crashes withpanic error: runtime error: index out of range [2] with length 2fromlinuxSystemTray.run's signal-handling goroutine.run()adds a single match fororg.freedesktop.DBus.NameOwnerChangedso it can re-register the StatusNotifierItem when the watcher restarts, then routes signals throughconn.Signal(sc). The handler indexessig.Body[2]unconditionally:In godbus,
conn.Signal(sc)delivers every signal the connection receives, not just the ones matching the per-channel rules. The systray opensdbus.SessionBus(), which returns a process-wide singleton connection — shared with anything else in the app that talks to the session bus. As soon as another part of the app subscribes to a 2-arg signal, it lands in the systray's channel and the unbounded index panics.defer handlePanic()in the goroutine recovers, but the default panic handler (defaultPanicHandler→globalApplication.fatal) then exits the process — so the user sees the app die.Same code is on master (
systemtray_linux.go:418) and v3.0.0-alpha.78.To Reproduce
Captured with this instrumentation in
linuxSystemTray.run:Output from a Wails v3 mail client running idle for ~2 minutes:
org.freedesktop.Notifications.ActionInvoked(u, s)andNotificationClosed(u, u)both have 2-element bodies per the Desktop Notifications spec. The mail client subscribes to them on the session bus to know when its notifications are clicked or auto-dismissed; that subscription causes godbus to start delivering them to every registeredSignal()channel, including the systray's.Repro is therefore: a Wails v3 app that creates a SystemTray AND has any other code on the session bus subscribing to a 2-arg (or 0/1-arg) signal will eventually crash on the first such signal received after startup.
Expected behaviour
The signal-handling goroutine must filter on the signal name (and bounds-check the body) before indexing it. Anything other than
org.freedesktop.DBus.NameOwnerChangedshould be ignored.Screenshots
No response
Attempted Fixes
The patch above stops the crash. Ready to PR.
System Details
Additional context
Original crash trace before instrumentation: