Skip to content

Commit 36ef3f8

Browse files
CyPackclaude
authored andcommitted
fix(doctor): detect virtiofsd outside PATH + document COWORK_VM_BACKEND
On Fedora/RHEL, virtiofsd installs to /usr/libexec/virtiofsd which is outside $PATH. On Debian/Ubuntu, it may be at /usr/lib/qemu/virtiofsd. The --doctor check uses `command -v` and reports a false warning. This commit: - Adds _doctor_find_virtiofsd() helper that probes common non-PATH locations (/usr/libexec/virtiofsd, /usr/lib/qemu/virtiofsd) - Shows the found path in --doctor output when not in PATH - Documents the COWORK_VM_BACKEND environment variable in docs/CONFIGURATION.md (host|bwrap|kvm backend override) - Adds Cowork troubleshooting section to docs/TROUBLESHOOTING.md covering VM timeout, virtiofsd PATH, and Fedora tmpfs /tmp issues - Shows COWORK_VM_BACKEND override in --doctor Cowork section Tested on Fedora 43 (GNOME/Wayland) with virtiofsd at /usr/libexec/. Fixes aaddrick#293 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dee729b commit 36ef3f8

3 files changed

Lines changed: 108 additions & 0 deletions

File tree

docs/CONFIGURATION.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Model Context Protocol settings are stored in:
1515
|----------|---------|-------------|
1616
| `CLAUDE_USE_WAYLAND` | unset | Set to `1` to use native Wayland instead of XWayland. Note: Global hotkeys won't work in native Wayland mode. |
1717
| `CLAUDE_MENU_BAR` | unset (`auto`) | Controls menu bar behavior: `auto` (hidden, Alt toggles), `visible` / `1` (always shown), `hidden` / `0` (always hidden, Alt disabled). See [Menu Bar](#menu-bar) below. |
18+
| `COWORK_VM_BACKEND` | unset (auto-detect) | Force a specific Cowork isolation backend: `kvm` (full VM), `bwrap` (bubblewrap namespace sandbox), or `host` (no isolation). See [Cowork Backend](#cowork-backend) below. |
1819

1920
### Wayland Support
2021

@@ -48,6 +49,42 @@ CLAUDE_MENU_BAR=visible claude-desktop
4849
export CLAUDE_MENU_BAR=visible
4950
```
5051

52+
### Cowork Backend
53+
54+
Cowork mode auto-detects the best available isolation backend:
55+
56+
| Priority | Backend | Isolation | Detection |
57+
|----------|---------|-----------|-----------|
58+
| 1 | KVM | Full QEMU/KVM VM | `/dev/kvm` (r/w) + `qemu-system-x86_64` + `/dev/vhost-vsock` |
59+
| 2 | bubblewrap | Namespace sandbox | `bwrap` installed and functional |
60+
| 3 | host | None (direct execution) | Always available |
61+
62+
To override auto-detection:
63+
64+
```bash
65+
# Force bubblewrap (recommended if KVM times out)
66+
COWORK_VM_BACKEND=bwrap claude-desktop
67+
68+
# Force host mode (no isolation)
69+
COWORK_VM_BACKEND=host claude-desktop
70+
71+
# Make permanent via desktop entry override
72+
mkdir -p ~/.local/share/applications/
73+
cat > ~/.local/share/applications/claude-desktop.desktop << 'EOF'
74+
[Desktop Entry]
75+
Name=Claude
76+
Exec=env COWORK_VM_BACKEND=bwrap /usr/bin/claude-desktop %u
77+
Icon=claude-desktop
78+
Type=Application
79+
Terminal=false
80+
Categories=Office;Utility;
81+
MimeType=x-scheme-handler/claude;
82+
StartupWMClass=Claude
83+
EOF
84+
```
85+
86+
Run `claude-desktop --doctor` to see which backend is selected and which dependencies are available.
87+
5188
## Application Logs
5289

5390
Runtime logs are available at:

docs/TROUBLESHOOTING.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,46 @@ If the global hotkey (Ctrl+Alt+Space) doesn't work, ensure you're not running in
8080

8181
See [CONFIGURATION.md](CONFIGURATION.md) for more details on the `CLAUDE_USE_WAYLAND` environment variable.
8282

83+
### Cowork: "VM connection timeout after 60 seconds"
84+
85+
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:
86+
87+
1. **First-boot initialization** — the guest VM may take longer than 60 seconds on first launch
88+
2. **vsock driver issues** — the guest initrd may lack the `vmw_vsock_virtio_transport` kernel module
89+
90+
**Fix:** Force the bubblewrap backend, which provides namespace-level isolation without a VM:
91+
92+
```bash
93+
COWORK_VM_BACKEND=bwrap claude-desktop
94+
```
95+
96+
See [CONFIGURATION.md](CONFIGURATION.md#cowork-backend) for how to make this permanent.
97+
98+
### Cowork: virtiofsd not found (Fedora/RHEL)
99+
100+
On Fedora and RHEL, `virtiofsd` installs to `/usr/libexec/virtiofsd` which is outside `$PATH`. The `--doctor` check may report `[WARN] virtiofsd: not found` even though the package is installed.
101+
102+
**Fix:** Create a symlink:
103+
104+
```bash
105+
sudo ln -s /usr/libexec/virtiofsd /usr/local/bin/virtiofsd
106+
```
107+
108+
On Debian/Ubuntu, the same issue can occur with `/usr/lib/qemu/virtiofsd`.
109+
110+
### Cowork: cross-device link error on Fedora tmpfs /tmp
111+
112+
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/`.
113+
114+
**Fix:** Set `TMPDIR` to a directory on the same filesystem:
115+
116+
```bash
117+
mkdir -p ~/.config/Claude/tmp
118+
TMPDIR=~/.config/Claude/tmp claude-desktop
119+
```
120+
121+
Or add `TMPDIR=%h/.config/Claude/tmp` to the `Exec=` line in your `.desktop` file.
122+
83123
### AppImage Sandbox Warning
84124

85125
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.

scripts/launcher-common.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,21 @@ _cowork_pkg_hint() {
232232
printf '%s' "$pkg_cmd $pkg"
233233
}
234234

235+
# Probe common non-PATH locations for virtiofsd
236+
# On Fedora/RHEL: /usr/libexec/virtiofsd
237+
# On Debian/Ubuntu: /usr/lib/qemu/virtiofsd
238+
# Returns 0 if found, 1 if not; prints path on stdout
239+
_doctor_find_virtiofsd() {
240+
local path
241+
for path in /usr/libexec/virtiofsd /usr/lib/qemu/virtiofsd; do
242+
if [[ -x $path ]]; then
243+
printf '%s' "$path"
244+
return 0
245+
fi
246+
done
247+
return 1
248+
}
249+
235250
_pass() { echo -e "${_green}[PASS]${_reset} $1"; }
236251
_fail() {
237252
echo -e "${_red}[FAIL]${_reset} $1"
@@ -468,6 +483,11 @@ print(len(servers))
468483
local _distro_id
469484
_distro_id=$(_cowork_distro_id)
470485

486+
# COWORK_VM_BACKEND override
487+
if [[ -n "${COWORK_VM_BACKEND:-}" ]]; then
488+
_info "Backend override: COWORK_VM_BACKEND=${COWORK_VM_BACKEND}"
489+
fi
490+
471491
# KVM access
472492
if [[ -e /dev/kvm ]]; then
473493
if [[ -r /dev/kvm && -w /dev/kvm ]]; then
@@ -505,6 +525,17 @@ print(len(servers))
505525

506526
if command -v "$_tool_bin" &>/dev/null; then
507527
_pass "$_tool_label: found"
528+
elif [[ $_tool_bin == 'virtiofsd' ]]; then
529+
local _vfsd_path
530+
_vfsd_path=$(_doctor_find_virtiofsd) || true
531+
if [[ -n $_vfsd_path ]]; then
532+
_pass "$_tool_label: found ($_vfsd_path, not in PATH)"
533+
else
534+
_warn "$_tool_label: not found"
535+
_info \
536+
"Fix: $(_cowork_pkg_hint \
537+
"$_distro_id" "$_tool_pkg")"
538+
fi
508539
else
509540
_warn "$_tool_label: not found"
510541
_info \

0 commit comments

Comments
 (0)