[BUG] Desktop app's self-generated .desktop entry breaks its own claude:// login handoff on Ubuntu — GIO refuses to load it
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Authorization for Claude Desktop not possible by Google. After successful Google auth., return from browser gives unhandled app error.
What Should Happen?
Claude Desktop app should open.
Error Messages/Logs
unhandled app
Steps to Reproduce
reproducible on Spark and x86
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.218
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Xterm
Additional Information
Title: [BUG] Desktop app's self-generated .desktop entry breaks its own claude:// login handoff on Ubuntu — GIO refuses to load it
Summary
Claude Desktop on Linux writes its own desktop entry to~/.local/share/applications/com.anthropic.Claude.desktop (markedX-Claude-Generated=true). That generated file cannot be loaded by GIO.
Because it shadows the packaged /usr/share/applications entry (same desktop
ID, higher priority), the x-scheme-handler/claude association disappears from
application enumeration while still resolving as a default.
The practical result: sign-in is impossible. After choosing a Google account in
the browser, the claude:// handoff back to the app dead-ends in a GNOME
"Open With… — No Apps Available" dialog, and login never completes.
Impact
Cannot sign in to the desktop app at all via the browser handoff
(https://claude.com/cai/login/app-google-auth?open_in_browser=1&hop_nonce=…).
Environment
Reproduced and independently verified on two machines:
| | Machine A | Machine B |
|---|---|---|
| OS | Ubuntu 24.04.5 LTS | Ubuntu 24.04.5 LTS |
| Arch | x86_64 | arm64 |
| App version | 1.49585.0 | 1.52386.0 |
| Browser | Opera (snap) | Firefox (snap) |
Both had previously worked; the failure appeared without any deliberate
configuration change.
The diagnostic signature
Identical output on both machines:
$ gio mime x-scheme-handler/claude
Default application for "x-scheme-handler/claude": com.anthropic.Claude.desktop
No registered applications
No recommended applications
A default that resolves, with empty Registered/Recommended lists. Control on the
same system behaves correctly:
$ gio mime x-scheme-handler/http
Default application for "x-scheme-handler/http": firefox_firefox.desktop
Registered applications:
firefox_firefox.desktop
Recommended applications:
firefox_firefox.desktop
An app chooser (which is what the "Open With" dialog is) enumerates viag_app_info_get_all_for_type(), so it correctly reports that nothing can handle
the scheme — even though xdg-mime query default x-scheme-handler/claude
returns com.anthropic.Claude.desktop and /usr/share/applications/mimeinfo.cache
contains x-scheme-handler/claude=com.anthropic.Claude.desktop;.
Confirmed cause (A/B test, both machines)
Moving the generated user-level file aside immediately restores enumeration,
because the desktop ID then resolves to the packaged entry instead:
$ mv ~/.local/share/applications/com.anthropic.Claude.desktop /tmp/
$ gio mime x-scheme-handler/claude
Default application for "x-scheme-handler/claude": com.anthropic.Claude.desktop
Registered applications:
com.anthropic.Claude.desktop
Recommended applications:
com.anthropic.Claude.desktop
Sign-in then completes normally. Restoring the file breaks it again.
On Machine A the sequence was run as an explicit three-step control:
- Baseline — default resolves, both lists empty.
sed -i '/^TryExec=/d'on the generated file — both lists still empty.- Move the (now
TryExec-free) file aside — both lists populate.
So the defect is the generated file itself, not the TryExec line it contains.
Ruled out
- Missing/incorrect registration —
xdg-mime query defaultreturns the
correct desktop ID; ~/.config/mimeapps.list has
x-scheme-handler/claude=com.anthropic.Claude.desktop.
- Stale
mimeinfo.cache—/usr/share/applications/mimeinfo.cache
contains the association; update-desktop-database changes nothing.
- xdg-desktop-portal cache — restarting
xdg-desktop-portal,
-gtk and -gnome changes nothing; no claude entries in the portal
permission store.
- Snap confinement — the failure reproduces in an unconfined shell via
gio mime, so it is not caused by the browser sandbox. (It is, however, an
independent second-order problem: inside the snap namespace
claude-desktop is not on $PATH, and $HOME is remapped to
~/snap/<app>/common.)
TryExec=claude-desktop— the generated file sets this and the packaged
file does not, making it the obvious suspect. Removing the line does not
restore enumeration, verified on both machines. It is not the cause.
- Broken entry point —
/usr/bin/claude-desktopis a valid, executable
symlink to ../lib/claude-desktop/claude-desktop.
- Malformed syntax —
desktop-file-validatereports the generated file
clean, apart from the same cosmetic Categories multi-main-category hint
that the packaged file also produces. All four groups named in Actions=
are present.
So the file is valid by every check available, yet GIO declines to load it.
The generated file
[Desktop Entry]
Name=Claude
Comment=Desktop application for Claude.ai
GenericName=AI Assistant
Keywords=AI;Chat;Assistant;Claude;Code;LLM;
Exec=claude-desktop %U
Icon=claude-desktop
Type=Application
StartupNotify=true
StartupWMClass=com.anthropic.Claude
SingleMainWindow=true
Categories=Utility;Development;
MimeType=x-scheme-handler/claude;
TryExec=claude-desktop
Actions=NewChat;NewCode;ContinueLast;NeedsInput;
X-Claude-Generated=true
[Desktop Action NewChat]
Name=New Chat
Exec=claude-desktop "claude://claude.ai/new?surface=chat&source=desktop_action"
[Desktop Action NewCode]
Name=New Claude Code Session
Exec=claude-desktop "claude://code/new?source=desktop_action"
[Desktop Action ContinueLast]
Name=Continue Last Claude Code Session
Exec=claude-desktop "claude://code/continue?session=last&source=desktop_action"
[Desktop Action NeedsInput]
Name=Sessions Waiting for You
Exec=claude-desktop "claude://code/needs-input?source=desktop_action"
(Comment lines present in the original are omitted here for brevity.)
For comparison, the packaged /usr/share/applications entry is the same file
without TryExec, without X-Claude-Generated, and with only the first two
actions. That one loads correctly.
Workaround
mv ~/.local/share/applications/com.anthropic.Claude.desktop /tmp/
Not durable — the app regenerates the file on subsequent launches, at which
point sign-in breaks again.
Expected behaviour
The generated entry should be loadable by GIO, or the app should not shadow the
working packaged entry with a generated one. As a robustness measure, the
desktop app could verify after writing thatg_app_info_get_all_for_type("x-scheme-handler/claude") is non-empty, and
remove its generated file if it is not.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Reproduced on Pop!_OS 22.04 (x11, GNOME), Claude Desktop 1.52386.3 (deb), Chrome stable 153 (deb, not snap). Same "Open With… — No Apps available" dead-end on the Google sign-in handoff, same
gio mimesignature (default resolves, Registered/Recommended empty).I think the root cause is narrower than "GIO refuses to load the file." GIO loads the generated entry fine. The user-level
mimeinfo.cacheis stale. The app writes~/.local/share/applications/com.anthropic.Claude.desktopbut never runsupdate-desktop-databaseon that directory, so~/.local/share/applications/mimeinfo.cachehas nox-scheme-handler/claudeline.The "Ruled out: stale mimeinfo.cache" section above only checked
/usr/share/applications/mimeinfo.cache. That one is correct, but it doesn't matter: because the user-level file shadows the system one (same desktop ID), GIO resolves the ID in the user dir and consults the user cache for the enumeration. The default still resolves because~/.config/mimeapps.listnames the ID directly. That is exactly the "default but nothing registered" split.Before:
Fix, non-destructive (generated file left in place):
Sign-in handoff then completes. This also explains why the
mvworkaround works (falls back to the system entry, whose cache was updated by the deb postinst) and why it isn't durable (the app rewrites the file, the user cache goes stale again).Suggested fix in the app: after writing the generated
.desktopfile, runupdate-desktop-database "$XDG_DATA_HOME/applications"(or~/.local/share/applications), and treat a non-zero exit or missing binary as a reason to skip writing the user-level entry and leave the packaged one in place. Alternatively, don't shadow the packaged entry at all; ship the four actions in the deb's desktop file instead.Workaround for anyone hitting this now:
update-desktop-database ~/.local/share/applications, then retry "Open Claude" in the browser. Re-run it if the app regenerates the file after an update.Follow-up on my own report — this is Machine B re-tested, not a new machine. Both of
my machines have taken updates since I filed, so versions have moved.
Machine B, Ubuntu 24.04.5 LTS, arm64, Firefox (snap), now on 1.52386.3 — same
version as the Pop!_OS report above. Still broken. The app prompted me to sign in and the
handoff dead-ended exactly as before.
The before-state is cleaner than "stale index": the user-level index did not exist at
all.
$ gio mime x-scheme-handler/claude
Default application for "x-scheme-handler/claude": com.anthropic.Claude.desktop
No registered applications
No recommended applications
$ ls -l ~/.local/share/applications/mimeinfo.cache
ls: cannot access '.../mimeinfo.cache': No such file or directory
$ stat -c '%n %y' ~/.local/share/applications/com.anthropic.Claude.desktop
.../com.anthropic.Claude.desktop 2026-09-12 00:36:36
So the app's entry had been sitting in that directory for a day with no index ever
created for it.
The non-destructive fix works here too, generated file untouched:
$ update-desktop-database ~/.local/share/applications
$ grep "x-scheme-handler/claude=" ~/.local/share/applications/mimeinfo.cache
x-scheme-handler/claude=com.anthropic.Claude.desktop;
$ gio mime x-scheme-handler/claude
Default application for "x-scheme-handler/claude": com.anthropic.Claude.desktop
Registered applications:
com.anthropic.Claude.desktop
Recommended applications:
com.anthropic.Claude.desktop
Sign-in handoff then completes.
Why this is intermittent across identical versions. Nothing routinely builds a
user-level
mimeinfo.cache— dpkg triggers refresh/usr/share/applicationsonly.So
~/.local/share/applicationsis indexed only if something incidentally ranupdate-desktop-databaseon it. My other machine (x86_64, 1.52386.0) has such anindex containing the correct line and is completely healthy on the same app
behaviour; this one never had one and fails deterministically. That may explain
reports that don't reproduce.
Worth noting from @runthyme -comment's output:
x-scheme-handler/claude-cli=claude-code-url-handler.desktop;is present in that user index, so the CLI's own handler registration does get indexed
correctly. The desktop app looks like the outlier here.
Correction to my original report: the "Ruled out: stale
mimeinfo.cache" bullet iswrong and should be disregarded. It only checked
/usr/share/applications/mimeinfo.cache.The user-level index is the one that governs, because the generated entry shadows the
packaged one under the same desktop ID.
*(Untested hypothesis, flagged as such: once a correct line exists, the app rewriting the
same file with the same desktop ID and MimeType shouldn't invalidate it — which would make
"re-run after every update" unnecessary. Breakage would instead require the index to be
absent, or rebuilt while the file is missing. I haven't tested this.)*
Can confirm this happened to me too, Ubuntu 26 and Ubuntu 24.