Files
claude-desktop-debian/docs/TROUBLESHOOTING.md
Aaddrick 0efa67d417 doctor: detect IBus/GTK misconfigurations that break input (#572)
* doctor: detect IBus/GTK misconfigurations that break input (#550)

Adds _doctor_check_im_modules helper covering the four input-method
failure modes from #545:

  - ibus-gtk3 package missing while GTK_IM_MODULE=ibus
  - GTK immodules cache stale (active module not listed by
    gtk-query-immodules-3.0 --update-cache fixes it)
  - XWayland session routing IBus through XIM (lossy for some IMEs;
    informational note pointing at CLAUDE_USE_WAYLAND=1 for native
    Wayland IME)
  - CLAUDE_GTK_IM_MODULE override visibility (informational, so
    users can verify the resolved value)

Each check is gated so it only fires when relevant — e.g. the
package check is skipped when GTK_IM_MODULE isn't ibus, the cache
check is skipped when gtk-query-immodules-3.0 isn't installed, and
the package check returns silently on distros without dpkg/rpm/pacman
to avoid false negatives.

Adds tests/doctor.bats with 17 cases covering each gating branch and
the _cowork_pkg_hint mapping for ibus-gtk3 (Arch maps to plain ibus
since it bundles the GTK3 immodule).

Hoists _distro_id resolution to the top of run_doctor so the IM
check and the existing Cowork section share one /etc/os-release
read.

Closes #550. Refs #545, #549.

Co-Authored-By: Claude <claude@anthropic.com>

* doctor: simplify IM-check helper and DRY out doctor.bats setup

Mechanical clean-up of the #550 diff after self-review:

scripts/doctor.sh
  - tighten the _doctor_check_im_modules docblock: drop the "each
    check is gated" paragraph (self-evident in the code) and inline
    the XWayland/XIM rationale into the failure-mode bullet
  - drop the inline section comments that just restated the next
    block's purpose; keep the rc=1/rc=2 comment because the value
    distinction is the load-bearing detail
  - replace the `local _pkg_rc=0; ... || _pkg_rc=$?; if ((_pkg_rc == 1))`
    dance with a `case $?` on the direct call

tests/doctor.bats
  - hoist the `command -v gtk-query-immodules-3.0 → not-found` shim
    into a `_skip_gtk_query` helper (it was duplicated across 11 of
    the 17 cases)
  - default `_pkg_installed() { return 2; }` in setup so per-test
    stubs only appear when the test cares about rc=0 or rc=1
  - drop dead `_skip_gtk_query` calls from cases where the function
    returns earlier (no IM selected, package warn fires) so the
    shim is only present where it actually changes behaviour

No behaviour change — all 17 doctor.bats cases still pass, plus the
68 launcher-common.bats cases. Shellcheck is unchanged from baseline.

Co-Authored-By: Claude <claude@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
2026-05-05 07:08:36 -04:00

10 KiB

< Back to README

Troubleshooting

Built-in Diagnostics

Run the --doctor flag to check your system for common issues:

# Deb install
claude-desktop --doctor

# AppImage
./claude-desktop-*.AppImage --doctor

This runs a series of checks and prints pass/fail results with suggested fixes:

Check What it verifies
Installed version Package version via dpkg
Display server Wayland/X11 detection and mode
Input method IBus/GTK immodule sanity (ibus-gtk3 installed, cache fresh, XWayland routing note)
Electron binary Existence and version
Chrome sandbox Correct permissions (4755/root)
SingletonLock Stale lock file detection
MCP config JSON validity and server count
Node.js Version (v20+ recommended for MCP)
Desktop entry .desktop file presence
Disk space Free space on config partition
Log file Log file size

Example output:

Claude Desktop Diagnostics
================================

[PASS] Installed version: 1.1.4498-1.3.15
[PASS] Display server: Wayland (WAYLAND_DISPLAY=wayland-0)
[PASS] Electron: found at /usr/lib/claude-desktop/node_modules/electron/dist/electron
[PASS] Chrome sandbox: permissions OK
[PASS] SingletonLock: no lock file (OK)
[PASS] MCP config: valid JSON
[PASS] Node.js: v22.14.0
[PASS] Desktop entry: /usr/share/applications/claude-desktop.desktop
[PASS] Disk space: 632284MB free
[PASS] Log file: 1352KB

All checks passed.

When opening an issue, include the output of --doctor to help with diagnosis.

Application Logs

Runtime logs are available at:

~/.cache/claude-desktop-debian/launcher.log

Common Issues

Window Scaling Issues

If the window doesn't scale correctly on first launch:

  1. Right-click the Claude Desktop tray icon
  2. Select "Quit" (do not force quit)
  3. Restart the application

This allows the application to save display settings properly.

Global Hotkey Not Working (Wayland)

If the global hotkey (Ctrl+Alt+Space) doesn't work, ensure you're not running in native Wayland mode:

  1. Check your logs at ~/.cache/claude-desktop-debian/launcher.log
  2. Look for "Using X11 backend via XWayland" - this means hotkeys should work
  3. If you see "Using native Wayland backend", unset CLAUDE_USE_WAYLAND or ensure it's not set to 1

Note: Native Wayland mode doesn't support global hotkeys due to Electron/Chromium limitations with XDG GlobalShortcuts Portal.

See CONFIGURATION.md for more details on the CLAUDE_USE_WAYLAND environment variable.

Keyboard Input Doesn't Work (IBus / GTK Input Method)

If typing into the chat does nothing, characters get swallowed, or dead-key sequences (e.g. `eè) don't compose, your GTK input module integration with the Electron-bundled GTK is broken. Common symptoms:

  • No characters appear when typing into any text field
  • The first keystroke after focus is dropped, subsequent ones work
  • CJK input methods (IBus, Fcitx) not engaging
  • Compose key / dead-key sequences silently drop

First step: run claude-desktop --doctor. It checks for the common misconfigurations and prints fix commands inline:

  • ibus-gtk3 package missing while GTK_IM_MODULE=ibus
  • GTK immodules cache stale (the active module isn't listed by gtk-query-immodules-3.0)
  • XWayland session routing IBus through XIM (lossy for some IMEs — set CLAUDE_USE_WAYLAND=1 to use native Wayland IME)
  • Active value of CLAUDE_GTK_IM_MODULE if you've set the override

If --doctor is clean but input still misbehaves, switch the launcher to a different GTK input module. Set CLAUDE_GTK_IM_MODULE and Claude Desktop will propagate it as GTK_IM_MODULE to Electron at startup:

# Bypass IBus entirely — uses the X Input Method (XIM) protocol
CLAUDE_GTK_IM_MODULE=xim claude-desktop

# To make it persistent, export it from your shell profile:
# echo 'export CLAUDE_GTK_IM_MODULE=xim' >> ~/.profile

Valid values: anything your GTK installation supports (xim, ibus, fcitx, simple, etc.). When the override is active, the launcher logs a line to ~/.cache/claude-desktop-debian/launcher.log:

GTK_IM_MODULE override: ibus -> xim (via CLAUDE_GTK_IM_MODULE)

Trade-off: xim is the lowest-common-denominator input module and does not support advanced IME features like CJK candidate windows or rich compose-key sequences. Only reach for it if your real input method (IBus/Fcitx) is broken; if you depend on CJK or compose, prefer fixing the IBus/Fcitx integration instead.

AppImage Sandbox Warning

AppImages run with --no-sandbox due to electron's chrome-sandbox requiring root privileges for unprivileged namespace creation. This is a known limitation of AppImage format with Electron applications.

For enhanced security, consider:

  • Using the .deb package instead
  • Running the AppImage within a separate sandbox (e.g., bubblewrap)
  • Using Gear Lever's integrated AppImage management for better isolation

Cowork on Ubuntu 24.04+ (AppArmor Blocks User Namespaces)

Ubuntu 24.04 ships with apparmor_restrict_unprivileged_userns=1 by default, which blocks the unprivileged user namespaces that Cowork's bubblewrap sandbox relies on. Symptoms:

  • claude-desktop --doctor reports bubblewrap: sandbox probe failed with Operation not permitted in stderr.
  • ~/.config/Claude/logs/cowork_vm_daemon.log contains bwrap is installed but cannot create a user namespace.
  • Cowork sessions hang at "Starting VM..." or loop on reconnect.

Permit user namespaces for bwrap via an AppArmor profile (one-time setup, requires sudo):

sudo tee /etc/apparmor.d/bwrap <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile bwrap /usr/bin/bwrap flags=(unconfined) {
    userns,

    include if exists <local/bwrap>
}
EOF

sudo apparmor_parser -r /etc/apparmor.d/bwrap

After applying the profile, run claude-desktop --doctor — the bubblewrap probe should pass, and Cowork should start without falling back to host-direct.

Security note: this grants /usr/bin/bwrap the unconfined profile plus the userns capability. It matches the behavior bwrap had on Ubuntu 22.04 and earlier, and on most other distros, but is a system-wide change that affects every program invoking /usr/bin/bwrap (not just Claude Desktop). Review the profile against your threat model before applying.

Credit: this workaround was contributed by @hfyeh in #351.

Cowork: "VM connection timeout after 60 seconds"

If Cowork fails with a VM timeout, the KVM backend is selected but the guest VM cannot connect back to the host via vsock within the timeout window. Common causes:

  1. First-boot initialization — the guest VM may take longer than 60 seconds on first launch
  2. vsock driver issues — the host may be missing the vhost_vsock module (sudo modprobe vhost_vsock), or the guest initrd may lack vmw_vsock_virtio_transport

Fix: Force the bubblewrap backend, which provides namespace-level isolation without a VM:

COWORK_VM_BACKEND=bwrap claude-desktop

See CONFIGURATION.md for how to make this permanent.

Cowork: virtiofsd not found (Fedora/RHEL)

On Fedora and RHEL, virtiofsd installs to /usr/libexec/virtiofsd which is outside $PATH. The --doctor check detects it there automatically and will show [PASS], but the KVM backend spawns virtiofsd by name at runtime and resolves it through $PATH only.

Fix: Create a symlink so the KVM backend can find it at runtime:

sudo ln -s /usr/libexec/virtiofsd /usr/local/bin/virtiofsd

On Debian/Ubuntu, the same issue can occur with /usr/lib/qemu/virtiofsd.

On Fedora, /tmp is a tmpfs by default. VM bundle downloads may fail with EXDEV: cross-device link not permitted when moving files from /tmp to ~/.config/Claude/.

Fix: Set TMPDIR to a directory on the same filesystem:

mkdir -p ~/.config/Claude/tmp
TMPDIR=~/.config/Claude/tmp claude-desktop

Or add TMPDIR=%h/.config/Claude/tmp to the Exec= line in your .desktop file.

Authentication Errors (401)

If you encounter recurring "API Error: 401" messages after periods of inactivity, the cached OAuth token may need to be cleared. This is an upstream application issue reported in #156.

To fix manually (credit: MrEdwards007):

  1. Close Claude Desktop completely
  2. Edit ~/.config/Claude/config.json
  3. Remove the line containing "oauth:tokenCache" (and any trailing comma if needed)
  4. Save the file and restart Claude Desktop
  5. Log in again when prompted

A scripted solution is also available at the bottom of this comment.

Uninstallation

For APT repository installations (Debian/Ubuntu)

# Remove package
sudo apt remove claude-desktop

# Remove the repository and GPG key
sudo rm /etc/apt/sources.list.d/claude-desktop.list
sudo rm /usr/share/keyrings/claude-desktop.gpg

For DNF repository installations (Fedora/RHEL)

# Remove package
sudo dnf remove claude-desktop

# Remove the repository
sudo rm /etc/yum.repos.d/claude-desktop.repo

For AUR installations (Arch Linux)

# Using yay
yay -R claude-desktop-appimage

# Or using paru
paru -R claude-desktop-appimage

# Or using pacman directly
sudo pacman -R claude-desktop-appimage

For .deb packages (manual install)

# Remove package
sudo apt remove claude-desktop
# Or: sudo dpkg -r claude-desktop

# Remove package and configuration
sudo dpkg -P claude-desktop

For .rpm packages

# Remove package
sudo dnf remove claude-desktop
# Or: sudo rpm -e claude-desktop

For AppImages

  1. Delete the .AppImage file
  2. Remove the .desktop file from ~/.local/share/applications/
  3. If using Gear Lever, use its uninstall option

Remove user configuration (all formats)

rm -rf ~/.config/Claude