Skip to content

fix(doctor): detect virtiofsd installed outside PATH on Debian#287

Closed
jarrodcolburn wants to merge 2 commits intoaaddrick:mainfrom
jarrodcolburn:fix/virtiofsd-non-path-detection
Closed

fix(doctor): detect virtiofsd installed outside PATH on Debian#287
jarrodcolburn wants to merge 2 commits intoaaddrick:mainfrom
jarrodcolburn:fix/virtiofsd-non-path-detection

Conversation

@jarrodcolburn
Copy link
Copy Markdown
Contributor

Problem

claude-desktop --doctor reports [WARN] virtiofsd: not found even when virtiofsd is properly installed. The runtime spawn in cowork-vm-service.js has the same blind spot and would fail at launch time.

Root Cause

The Debian virtiofsd package intentionally installs its binary outside of $PATH:

  • /usr/libexec/virtiofsd — primary binary (/usr/libexec/ is for executables invoked by programs, not users directly, per FHS)
  • /usr/lib/qemu/virtiofsd — symlink for QEMU compatibility

This is not an accident. The package's own vhost-user registration file (/usr/share/qemu/vhost-user/50-virtiofsd.json) explicitly hard-codes the binary path so QEMU can locate it:

{
  "description": "virtiofsd vhost-user-fs",
  "type": "fs",
  "binary": "/usr/libexec/virtiofsd",
  ...
}

The previous command -v virtiofsd check only searches $PATH, so it always misses this installation.

Fix

scripts/launcher-common.sh

Replaces the generic command -v loop entry for virtiofsd with a dedicated check that:

  1. Tries $PATH first (covers distros that do put it in PATH)
  2. Falls back to probing /usr/libexec/virtiofsd and /usr/lib/qemu/virtiofsd
  3. Reports the resolved path in the [PASS] message for clarity

scripts/cowork-vm-service.js

Adds a findVirtiofsd() helper with the same probe order, and guards the virtiofsd spawn behind a found-path check so it fails cleanly rather than erroring on a bad command name.

Verification

On a system with virtiofsd installed via apt install virtiofsd:

Before: [WARN] virtiofsd: not found
After: [PASS] virtiofsd: found (/usr/libexec/virtiofsd)


Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
85% AI / 15% Human
Claude: research, implementation, PR
Human: problem identification, direction, review

jarrodcolburn and others added 2 commits March 5, 2026 10:57
On Debian/Ubuntu, the virtiofsd package intentionally installs its binary
to /usr/libexec/virtiofsd (with a symlink at /usr/lib/qemu/virtiofsd)
rather than a PATH-accessible location like /usr/bin. This is by design:
/usr/libexec/ is reserved for executables invoked by other programs, not
end users, and the package's vhost-user registration file
(/usr/share/qemu/vhost-user/50-virtiofsd.json) explicitly points QEMU to
/usr/libexec/virtiofsd as the canonical binary location.

The previous `command -v virtiofsd` check only searches PATH, producing a
false [WARN] even when virtiofsd is properly installed. Likewise the
runtime spawn used just 'virtiofsd', which would fail at launch time.

Fix both call sites:
- launcher-common.sh: replace the generic tool-loop entry with a dedicated
  check that tries PATH first, then probes the known non-PATH locations
  and reports the resolved path in the [PASS] message
- cowork-vm-service.js: add findVirtiofsd() helper using the same probe
  order, and guard the virtiofsd spawn behind a path-found check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add missing blank line between LOG_FILE constant and findVirtiofsd()
function, and add a JSDoc comment documenting the function's purpose
and return value.

Co-Authored-By: Claude <claude@anthropic.com>
@sebazic92
Copy link
Copy Markdown

Temporary workaround while waiting for this PR to be merged:

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

To revert after updating to a release that includes this PR:

sudo rm /usr/local/bin/virtiofsd

Copy link
Copy Markdown
Owner

@aaddrick aaddrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! This is solid work identifying a real problem. The Debian virtiofsd package intentionally installs outside $PATH, and command -v will always miss it. The fix direction is right.

Shell changes — good to go

The launcher-common.sh changes are clean. Style is correct — tabs, [[ ]], local declarations, underscore-prefixed variables matching the surrounding code. The detection logic (PATH first, then well-known locations) is sound. Removing virtiofsd from the generic tool loop makes sense. The _warn severity is appropriate since virtiofsd is optional.

JS changes — need a rebase

The PR branch is based on a version of cowork-vm-service.js from before a significant overhaul. Since this PR was opened, the file has received ~17 commits across PRs #300, #301, and #302 that added:

  • virtiofsd socket wait loop (QEMU needs the socket before starting)
  • bundlePath handling (rootfs comes from ~/.config/Claude/vm_bundles/, not VM_BASE_DIR)
  • smol-bin VHDX-to-qcow2 conversion
  • startupStep event emissions
  • Guest message envelope format fixes
  • setDebugLogging handler
  • Shared memory backend for virtiofs

A merge will conflict and could silently drop critical logic. Please rebase onto current main.

The findVirtiofsd() helper itself is well-structured — the candidate path list covers the common Debian and QEMU-compat locations. After rebasing, it should slot in cleanly. The merged startVM should look roughly like:

const virtiofsdBin = findVirtiofsd();
if (virtiofsdBin) {
    try {
        // spawn virtiofsd using virtiofsdBin instead of 'virtiofsd'
        // ... (keep existing socket wait loop, error handler, etc.)
    } catch (e) {
        log(`KvmBackend: virtiofsd not available: ${e.message}`);
        this.virtiofsdProcess = null;
    }
} else {
    log('KvmBackend: virtiofsd not found, skipping home directory share');
    this.virtiofsdProcess = null;
}

One thing to watch: virtiofsSock is currently declared before the try block so it's available for the QEMU chardev argument later. Make sure it stays accessible after the rebase.

Happy to help if you run into conflicts — there's a lot of new code in this file. Thanks for the contribution!


Written by Claude Opus 4.6 via Claude Code

@aaddrick
Copy link
Copy Markdown
Owner

Hey! Thanks for catching this issue and putting together a fix. The virtiofsd PATH detection problem on Debian is real and your PR helped surface it clearly.

We're going to close this in favor of #324 by CyPack, which covers the same Debian fix along with Fedora support and COWORK_VM_BACKEND documentation. It ended up being a superset of this work.

We'll credit you in the acknowledgments when #324 merges since you identified the problem first.


Written by Claude Opus 4.6 via Claude Code

@aaddrick aaddrick closed this Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants