What happened
Desktop app on Linux (AppImage). Clicking Sign in (T3 Connect) opens the Clerk widget; choosing Google and completing the account picker ends in the browser asking to open the callback with xdg-open. Confirming does nothing useful: a second, empty browser window opens with the t3code:// URL, the in-app Clerk widget keeps spinning, and the user is never signed in. CLI login (bunx t3) works, so the account itself is fine.
Diagnosis
DesktopLinuxUrlHandler.ts writes the URL-handler desktop entry with a double-quoted Exec path (escapeDesktopEntryExecArgument wraps every value in "..."):
Exec="/home/<user>/.local/bin/t3code.AppImage" %U
The Desktop Entry spec allows this, but xdg-utils' shell fallback does not implement Exec quoting. On any desktop that xdg-open does not recognize (sway, Hyprland, i3, river, and so on) it takes the generic path, and search_desktop_file does:
command="$(get_key "${file}" "Exec" | first_word)" # -> "/home/<user>/.local/bin/t3code.AppImage" WITH the quotes
if command -v "$command" >/dev/null; then # fails: no such command
... env "$command" "$@"
fi
# falls through to the $BROWSER fallback
command -v fails on the quoted string, the handler is skipped, and xdg-open falls back to $BROWSER / the default web browser, which is why a second browser window opens with the t3code:// URL. The running app never receives the callback, so the OAuth flow never completes. This is xdg-utils issues #151 and #279 (see Related); it has been open since 2019, so T3 cannot rely on it being fixed downstream.
Everything else in the registration chain was fine on this machine: the entry exists and points at the current AppImage, mimeinfo.cache lists it for x-scheme-handler/t3code, and xdg-mime query default x-scheme-handler/t3code returns com.t3tools.T3Code.desktop. Removing the quotes from Exec is the only change needed for xdg-open to launch it (verified below).
Desktops where xdg-open delegates to gio open or kde-open parse Exec correctly, which is why GNOME/KDE/COSMIC users are not hit and why #10354 was solved by the cache refresh alone.
Possible fix direction: only quote the Exec argument when it contains characters that need it (spaces, quotes, $, backticks, %), or point Exec at a small wrapper script at a quote-free path. Not patched locally.
Steps to reproduce
Standalone, no T3 needed (xdg-utils 1.2.1, with XDG_CURRENT_DESKTOP set to something xdg-open does not know, e.g. sway):
T=$(mktemp -d); mkdir -p "$T/share/applications" "$T/config"
printf '#!/bin/sh\necho "HANDLER: $*" >> %s/log\n' "$T" > "$T/handler.sh"
printf '#!/bin/sh\necho "BROWSER FALLBACK: $*" >> %s/log\n' "$T" > "$T/browser.sh"
chmod +x "$T"/*.sh
printf '[Desktop Entry]\nType=Application\nName=Quoted\nExec="%s" %%U\nMimeType=x-scheme-handler/q1;\n' "$T/handler.sh" > "$T/share/applications/q1.desktop"
printf '[Desktop Entry]\nType=Application\nName=Plain\nExec=%s %%U\nMimeType=x-scheme-handler/q2;\n' "$T/handler.sh" > "$T/share/applications/q2.desktop"
printf '[Default Applications]\nx-scheme-handler/q1=q1.desktop\nx-scheme-handler/q2=q2.desktop\n' > "$T/config/mimeapps.list"
export XDG_DATA_HOME="$T/share" XDG_DATA_DIRS="$T/share" XDG_CONFIG_HOME="$T/config" BROWSER="$T/browser.sh" XDG_CURRENT_DESKTOP=sway
xdg-open q1://x; xdg-open q2://x; cat "$T/log"
Output:
BROWSER FALLBACK: q1://x
HANDLER: q2://x
In T3 Code:
- Install the Linux AppImage on a session whose desktop xdg-open treats as
generic (sway here).
- Launch the app; it writes
~/.local/share/applications/com.t3tools.T3Code.desktop with the quoted Exec.
- Settings → Sign in → Google, finish the account picker in the browser.
- The browser prompts to open
t3code://app/... with xdg-open. Confirm.
- A new browser window opens with the
t3code:// URL; the app never receives it and the Clerk widget spins forever.
Version
0.0.46-nightly.20261004.2657 (tag v0.0.46-nightly.20261004.2657, commit efecd3cf)
Environment
NixOS, Linux 6.18.33 x86_64, sway (Wayland), xdg-utils 1.2.1, AppImage launched through nixpkgs appimage-run (bubblewrap FHS sandbox), default browser Helium 0.10.7.1 (Chromium based). Node v26.8.2.
Evidence
$ cat ~/.local/share/applications/com.t3tools.T3Code.desktop
[Desktop Entry]
Type=Application
Name=T3 Code (Nightly)
Exec="/home/<user>/.local/bin/t3code.AppImage" %U
Icon=/home/<user>/.local/share/icons/com.t3tools.T3Code.desktop.png
Terminal=false
NoDisplay=true
StartupNotify=false
MimeType=x-scheme-handler/t3code;
$ grep x-scheme-handler/t3code ~/.local/share/applications/mimeinfo.cache
x-scheme-handler/t3code=com.t3tools.T3Code.desktop;t3code-url-handler.desktop;
$ xdg-mime query default x-scheme-handler/t3code
com.t3tools.T3Code.desktop
$ BROWSER=/tmp/t/browser.sh xdg-open "t3code://app/triage-test"; cat /tmp/t/log
BROWSER FALLBACK CALLED: t3code://app/triage-test
# xdg-open 1.2.1, search_desktop_file():
command="$(get_key "${file}" "Exec" | first_word)"
if command -v "$command" >/dev/null; then
Related issues
Fix applied or workaround
Nothing changed on the machine by triage. Workaround for the user: an extra handler desktop entry with an unquoted Exec, set as the x-scheme-handler/t3code default in mimeapps.list. Because the app rewrites its own entry on every start, the workaround has to live in a separate file.
A second, machine-specific problem was also found and is not part of this issue: the user's default browser runs through a wrapper that sets HOME/XDG_DATA_HOME to a different directory, so the xdg-open it spawns does not see ~/.local/share/applications at all.
Filed by
Claude Fable 5.1 (Claude Code) via t3 triage, on behalf of the user.
What happened
Desktop app on Linux (AppImage). Clicking Sign in (T3 Connect) opens the Clerk widget; choosing Google and completing the account picker ends in the browser asking to open the callback with xdg-open. Confirming does nothing useful: a second, empty browser window opens with the
t3code://URL, the in-app Clerk widget keeps spinning, and the user is never signed in. CLI login (bunx t3) works, so the account itself is fine.Diagnosis
DesktopLinuxUrlHandler.tswrites the URL-handler desktop entry with a double-quoted Exec path (escapeDesktopEntryExecArgumentwraps every value in"..."):The Desktop Entry spec allows this, but xdg-utils' shell fallback does not implement Exec quoting. On any desktop that xdg-open does not recognize (sway, Hyprland, i3, river, and so on) it takes the
genericpath, andsearch_desktop_filedoes:command -vfails on the quoted string, the handler is skipped, and xdg-open falls back to$BROWSER/ the default web browser, which is why a second browser window opens with thet3code://URL. The running app never receives the callback, so the OAuth flow never completes. This is xdg-utils issues #151 and #279 (see Related); it has been open since 2019, so T3 cannot rely on it being fixed downstream.Everything else in the registration chain was fine on this machine: the entry exists and points at the current AppImage,
mimeinfo.cachelists it forx-scheme-handler/t3code, andxdg-mime query default x-scheme-handler/t3codereturnscom.t3tools.T3Code.desktop. Removing the quotes from Exec is the only change needed for xdg-open to launch it (verified below).Desktops where xdg-open delegates to
gio openorkde-openparse Exec correctly, which is why GNOME/KDE/COSMIC users are not hit and why #10354 was solved by the cache refresh alone.Possible fix direction: only quote the Exec argument when it contains characters that need it (spaces, quotes,
$, backticks,%), or point Exec at a small wrapper script at a quote-free path. Not patched locally.Steps to reproduce
Standalone, no T3 needed (xdg-utils 1.2.1, with
XDG_CURRENT_DESKTOPset to something xdg-open does not know, e.g.sway):Output:
In T3 Code:
generic(sway here).~/.local/share/applications/com.t3tools.T3Code.desktopwith the quoted Exec.t3code://app/...with xdg-open. Confirm.t3code://URL; the app never receives it and the Clerk widget spins forever.Version
0.0.46-nightly.20261004.2657 (tag
v0.0.46-nightly.20261004.2657, commitefecd3cf)Environment
NixOS, Linux 6.18.33 x86_64, sway (Wayland), xdg-utils 1.2.1, AppImage launched through nixpkgs
appimage-run(bubblewrap FHS sandbox), default browser Helium 0.10.7.1 (Chromium based). Node v26.8.2.Evidence
Related issues
mimeinfo.cache(fix(desktop): make Linux URL handlers discoverable with the app icon #8673). Not a duplicate: here the cache and the default are already correct and the failure is xdg-open's Exec parsing on the generic path.Fix applied or workaround
Nothing changed on the machine by triage. Workaround for the user: an extra handler desktop entry with an unquoted Exec, set as the
x-scheme-handler/t3codedefault inmimeapps.list. Because the app rewrites its own entry on every start, the workaround has to live in a separate file.A second, machine-specific problem was also found and is not part of this issue: the user's default browser runs through a wrapper that sets
HOME/XDG_DATA_HOMEto a different directory, so the xdg-open it spawns does not see~/.local/share/applicationsat all.Filed by
Claude Fable 5.1 (Claude Code) via
t3 triage, on behalf of the user.