Repository navigation
Settings "Open configuration file" fails with a generic error on Linux hosts without xdg-open; the real error is hidden
#804
yuhenghuang
started this conversation in
General
Replies: 1 comment
|
你这个判断是对的,我在 代码链路确认
结论这确实是个值得修的 bug,两点都成立:
临时绕过
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
On a Linux host without
xdg-open(e.g. a minimal container / VS Code dev container), the Settings → General → "Open configuration file" button always fails, showing only the generic red text "Could not open configuration file". The underlying cause — the host spawnsxdg-openunconditionally and it does not exist (spawn xdg-open ENOENT) — is never surfaced to the user.Environment
@deepseek-ai/dsh0.1.0-rc.6 (global npm install)linuxkitcontainer), running as a VS Code Remote-Containers dev container — no desktop environmentDISPLAY=:0is set but no X server is actually running (stale socket);BROWSERis set (to a VS Code helper)Steps to reproduce
dsh webon a Linux host wherecommand -v xdg-openreturns nothing (any bare container).Expected behavior
On a host with no desktop opener, "open in the user's editor" must be a handoff, not a local spawn. The button should either:
$BROWSER), orcode --reuse-window <path>),and when no handoff is possible, show a clear message that includes the resolved document path — never a generic error.
Actual behavior
A red inline alert appears: "Could not open configuration file". The real server error —
path open failed: spawn xdg-open ENOENT— is never displayed.Root cause
Three compounding issues:
Host: the Linux opener is hardcoded to
xdg-openwith no fallback.settings.openDocumentresolves the document viaprepareDocument()then callsopenNativeTextFile, whose Linux branch unconditionally runsxdg-open <path>(dsh-host-apiproxy→native-path-opener.js,openNativePathWithIntent). There is no$EDITOR/$VISUALfallback, no configurable opener command, and no catch — a missing binary propagates out and is wrapped byopenTargetaspath open failed: <message>. (Other domains do have a capability gate —agentPresets.openDocumentalready returns{ opened: false, path }whencanOpenPaths()is false.)Headless detection is unreliable.
canOpenNativePath()answers true on Linux wheneverDISPLAYorWAYLAND_DISPLAYis set, even when the display socket is dead / no display server runs — so surfaces advertise native open on hosts where it cannot work. (The Settings button itself renders based onhasDocument, independent of this, so it is shown even on headless hosts.)Client: the real error is swallowed behind a generic string. The settings header action (
SettingsDocumentAction) renders the localizedopenDocument.error("Could not open configuration file") whenever any error occurred, whileSettingsDocumentStore.open()stores the actual server message instate.error— which the UI never renders.Suggested fixes
On a host with no desktop opener, "open in the user's editor" cannot be a local spawn — a container cannot push a file into the user's editor directly. It must be a handoff. Two viable handoff paths, best as a ladder:
openInBrowservia$BROWSER, used for browser-renderable documents), and in container/VS Code setups$BROWSERis typically set to a helper that lands the tab in the user's real browser. This is the robust path: it needs no desktop and no editor handshake. (A served view is read-only by default — the Settings panel already renders the namespaces and can serve as the in-browser editor.)REMOTE_CONTAINERS_IPC,~/.vscode-server, or the connection token), open the path with the remote CLI (code --reuse-window <path>) so the file opens in the user's attached VS Code window. This works only while the user's window is actually attached, so it must fall back to path 1 when attachment cannot be confirmed.Plus the generic hygiene items:
xdg-open→$VISUAL/$EDITOR→ served-URL browser open → a clear error that names the document path (e.g. "no opener available on this host; the file is at "), or a copy-path affordance.SettingsDocumentStorein the action UI (at least truncated) instead of the generic locale string.canOpenNativePathdetect a dead display (or havesettings.openDocumentmirroragentPresets.openDocumentand return{ opened: false, path }when no opener can run).Related discussions
No existing discussion covers this specific bug (Settings → "Open configuration file" failing on a headless Linux host with
spawn xdg-open ENOENTand a hidden error). Two nearby threads share the same underlying machinery and are worth linking:host.openPath/openNativePath) failing to reach the user's editor from the web UI, with feedback swallowed by a.catch(() => {}). Different surface (tool-result file chips) and different failure mode (remote-vs-local), same design gap: web "open" gestures must be handoffs, not host-native spawns.Notes
~/.dsh/settings.yamlexists, external edits hot-reload (chokidar watch), and Settings-panel edits persist correctly. Only the "open in editor" gesture is broken.$BROWSERpoints at the VS Code browser helper (so a served URL reaches the user's browser), and the VS Code remote CLI connects while a window is attached — hence the ladder above.execFile("xdg-open", ["~/.dsh/settings.yaml"])fails withspawn xdg-open ENOENT, and the client renders the generic string in response.All reactions