[BUG] [Claude Desktop Linux] Tray icon degrades to a placeholder: StatusNotifierItem methods double-exported, leaving the D-Bus object with no interfaces

Status Open
Maintainer reply None cached
Activity 1 comment · opened Aug 24, 2026

Summary

On Linux/GNOME, Claude Desktop's tray icon paints correctly for roughly a minute after the app is opened, then degrades into a generic placeholder glyph. The cause appears to be that the app exports the org.kde.StatusNotifierItem methods twice on the same object path. The collision leaves the D-Bus object exporting no interfaces at all, so the tray host has nothing to render.

Stale registrations also accumulate: each open/close cycle can leave another dead item registered with StatusNotifierWatcher, so multiple placeholder glyphs pile up in the panel.

Environment

| | |
|---|---|
| Claude Desktop | 1.34493.1 (.deb from downloads.claude.ai/claude-desktop/apt/stable) |
| Electron / Chrome | Electron/42.9.2 · Chrome/148.0.7778.280 |
| OS | Ubuntu 26.04 |
| Desktop | GNOME Shell 50.1, Wayland |
| Tray host | ubuntu-appindicators@ubuntu.com (Ubuntu default) |

What happens

  1. Open the app — the correct Claude asterisk appears in the panel.
  2. After ~1 minute it becomes a generic placeholder glyph.
  3. Repeating open/close leaves additional placeholder glyphs behind.

Evidence

The app's own stderr — the same methods exported twice:

ERROR:dbus/exported_object.cc:103 org.kde.StatusNotifierItem.Activate is already exported
ERROR:dbus/exported_object.cc:103 org.kde.StatusNotifierItem.ContextMenu is already exported
ERROR:dbus/exported_object.cc:103 org.kde.StatusNotifierItem.Scroll is already exported
ERROR:dbus/exported_object.cc:103 org.kde.StatusNotifierItem.SecondaryActivate is already exported

The resulting object exports nothing:

$ gdbus introspect --session --dest <claude-bus-name> --object-path /StatusNotifierItem
node /StatusNotifierItem {
};

So every property read fails, while the name stays registered with the watcher:

$ gdbus call --session --dest <claude-bus-name> --object-path /StatusNotifierItem \
    --method org.freedesktop.DBus.Properties.GetAll org.kde.StatusNotifierItem
Error: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: Method is no longer available

The tray host throws repeatedly trying to read it:

getProperty@ubuntu-appindicators@ubuntu.com/dbusProxy.js:93:33
refreshProperty@ubuntu-appindicators@ubuntu.com/appIndicator.js:322:48
_refreshOwnProperties@ubuntu-appindicators@ubuntu.com/appIndicator.js:204:51
_onSignalAsync@ubuntu-appindicators@ubuntu.com/appIndicator.js:261:50
async*_onSignal@ubuntu-appindicators@ubuntu.com/appIndicator.js:218:14

Scope: what is and isn't Claude-specific

I initially wrote Slack up as a healthy control on this machine. That was wrong, and I want to be precise about it:

  • Not Claude-specific: the placeholder rendering also affects Slack here. Both Electron tray items degrade to a generic placeholder glyph after a while, and the tray host throws while refreshing item properties (getProperty / refreshProperty stack above). The placeholder symptom therefore looks host-side, and a GNOME/appindicator bug may be involved. Empirically, the number of placeholder glyphs tracked the number of registered items exactly: two items → two glyphs; killing Claude Desktop removed one; dropping Slack's registration removed the other.
  • Claude-specific and independent of that: the is already exported collision and the resulting interface-less object. Slack's item, by contrast, still answers property reads normally:
Slack (Electron/43.4.0):  Status: Active   IconName: status_icon_0
                          IconThemePath: /tmp/org.chromium.Chromium.XXXXXX  (22x22 RGBA PNG, valid, present)

Slack's object serves its properties; Claude Desktop's serves none. That difference is the part being reported here.

Distinct from existing issues

  • #24041 (closed): icon is never created on 1.1.2321 due to a minifier ReferenceError and menuBarEnabled gating. Here the icon is created and paints correctly first; menuBarEnabled is set; and ~/.config/Claude/logs/main.log contains no tray, icon, or ReferenceError lines.
  • #77170 / #77171: dark-panel visibility and colour-scheme reactivity. This is not a theming problem — the object stops exporting interfaces entirely.
  • electron/electron#52674: same end symptom, but that is an Electron 43.3 regression. This build is on Electron 42.9.2, and Slack on 43.4.0 is unaffected here.

Related: "Quit" does not quit

From the tray menu, Quit closes the window and tears down the tray object but leaves the process tree running. The app itself logs its footprint every minute while "quit":

[process-memory] trigger=interval tree_rss_sum=861MB tree_footprint_sum=569MB electron(7)=822MB children(5)=39MB

Independently measured: 15 processes, 855 MB RSS / 568 MB PSS, resident 13 h after the window was closed. systemd --user also shows fresh app-com.anthropic.Claude-<pid>.scope units from a process that never exited. This may share a root cause with the tray lifecycle bug.

Reproduction

  1. Ubuntu 26.04, GNOME 50.1 Wayland, default ubuntu-appindicators.
  2. Launch Claude Desktop 1.34493.1; confirm the correct tray icon.
  3. Wait ~1 minute — it becomes a placeholder.
  4. Close and reopen the window a few times — extra placeholders accumulate.
  5. gdbus introspect the item's /StatusNotifierItem; it exports no interfaces.

Workaround

Kill the process tree (not Quit); the stale registration then clears from StatusNotifierWatcher on its own:

kill $(pgrep -f 'lib/claude-desktop')

If placeholders persist, rebuild the tray host:

gnome-extensions disable ubuntu-appindicators@ubuntu.com
gnome-extensions enable  ubuntu-appindicators@ubuntu.com

Expected

Register the StatusNotifierItem methods once per item, tear the object and its watcher registration down on hide/quit, and let Quit exit the process tree.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗