You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cli: invalid directory arg shows raw ENOENT chdir stack trace instead of friendly error #49663
Running opencode <unknown-arg> treats the arg as <directory> and prints a raw ENOENT ... chdir error with an internal Bun stack trace (/$bunfs/root/chunk-*.js) instead of a friendly validation error. Exit code is still 0.
Install/channel: latest (npm-opencode-cli via mise: ~/.local/share/mise/installs/npm-opencode-cli/latest), update: disable in config
Active plugins: global MCP servers context7, exa, kaggle enabled, chrome-devtools disabled; CLI plugin ./herdr-opencode; no project-local opencode.json(c) found
Reproduction
Open a shell in a directory without a ./ls entry (e.g. ~).
Run opencode ls.
Observe the error output.
Same result with opencode foobar123 and opencode /nonexistent-dir-xyz.
Expected Behavior
Friendly validation error such as directory 'ls' does not exist plus usage hint (opencode <subcommand> [flags] [<directory>] / opencode --help), with non-zero exit code. No internal paths in output.
Actual Behavior
Raw error log with internal stack frame, exit 0:
~ ❯ opencode ls
[08:36:57.084] ERROR (#1): Error: ENOENT: no such file or directory, chdir '/home/broto' -> 'ls'
at chdir (unknown)
at <anonymous> (/$bunfs/root/chunk-3vv35md2.js:96:6419)
opencode --help confirms USAGE: opencode <subcommand> [flags] [<directory>] with no ls subcommand, so the arg falls through to <directory> and fails in chdir.
Reproduced on current v2 at eb0e26b with Bun 1.4.2 using an isolated CLI subprocess: the missing directory prints the chdir stack to stdout, with empty stderr. The exit status is already 1 on this head. I am preparing a narrow fix for the directory error output, with subprocess coverage for missing paths, file arguments, and a valid-directory control. This keeps the separate remote-directory routing change in #47818 out of scope.
Confirmed on v2.1.2 (current latest) on Windows — the raw Bun stack is still leaked, and there are two additional details that seem worth adding to this report.
Repro (Windows, opencode 2.1.2, npm latest)
> opencode /pluginsError: ENOENT: no such file or directory, chdir 'C:\Users\<user>' -> '/plugins' at chdir (unknown) at <anonymous> (B:/~BUN/root/chunk-r7jmhtz7.js:95:6479)
Exit code 1. The message goes to stderr; stdout is empty (0 bytes).
Observations beyond the original report
1. Behavior since 2.0.7 has partially changed, but the raw stack is still exposed. The original report observed exit 0 with the stack on stdout and empty stderr. On 2.1.2 the exit code is 1 and the stack is on stderr. The internal frame (B:/~BUN/root/chunk-*.js) still reaches the user, so the underlying UX problem is unfixed — only the plumbing around it moved.
2. Windows resolves the POSIX-style argument against the current drive root, and the error never shows the path actually attempted./plugins is not treated as an opaque invalid path — on Windows it normalizes to C:\plugins, i.e. the root of the drive the shell is on (path.resolve('/plugins') → C:\plugins). The error message prints the un-normalized target ('/plugins') next to the resolved source, so the user never sees the path the process really tried, and C:\plugins looks like a plausible system location rather than a typo.
Confirmed identical for /plugin, /nonexistent-dir-xyz, and any other /... value:
> opencode /pluginError: ENOENT: no such file or directory, chdir 'C:\Users\<user>' -> '/plugin'
3. The /plugins spelling is a genuine trap, and a targeted hint would fix this class of report.
plugins.list in the TUI does declare slash: { name: "plugins" } (see #47345), so /plugins is a valid TUI command. But it is also the natural thing to type in a shell, where it is silently consumed as the positional <directory> argument and produces this stack trace. A friendly error could special-case this:
'/plugins' looks like an OpenCode TUI command. Run it inside the OpenCode prompt, or use \opencode plugin list` from the shell.`
That single hint covers the whole /mcps, /agents, /skills, /models, /themes family, and would have made this original report unnecessary in the first place.
Environment
opencode version: 2.1.2
OS: Windows_NT 10.0.20348 (win32 x64)
Terminal: TERM=xterm-256color, TERM_PROGRAM unset
Shell: PowerShell 7.6.6 (ComSpec: cmd.exe)
Install/channel: latest, npm (@opencode/cli@2.1.2), shared background service
Active plugins: none configured — 88 builtin, all active; MCP servers playwright (local) and context7 (remote)
Reproduced consistently (3/3 for /plugins, plus /plugin and /nonexistent-dir-xyz). No secrets included; paths redacted.
Thanks for the detailed report! I reproduced this on 2.0.7. From an empty directory, opencode ls, opencode foobar123 and opencode /nonexistent-dir-xyz each print a raw ENOENT: no such file or directory, chdir ... -> '<arg>' error with an internal stack frame, instead of a friendly "directory does not exist" message. It still happens on the latest dev (950111f). The CLI calls chdir on the positional argument without checking it first.
One difference: here the exit code was 1, not 0, on both 2.0.7 and dev. If you still see 0, could you check with opencode ls; echo $? directly in bash? A shell prompt or wrapper may be reporting something else.
The script below reproduces it.
Reproduction script (repro.sh)
#!/usr/bin/env bash# Reproduces #49663: invalid <directory> positional arg -> raw ENOENT chdir log, exit 0# Usage: ./repro.sh (uses `opencode` on PATH)# OC_DEV=/path/to/repo ./repro.sh (runs from source checkout)set -u
run() {
if [ -n"${OC_DEV:-}" ];then
bun --conditions=browser --preload="$OC_DEV/packages/tui/node_modules/@opentui/solid/scripts/preload.js""$OC_DEV/packages/cli/src/index.ts""$@"else
opencode "$@"fi
}
dir=$(mktemp -d);cd"$dir"echo"version: $(run --version 2>&1)"forargin ls foobar123 /nonexistent-dir-xyz;doecho"--- opencode $arg"
timeout 30 bash -c "$(declare -f run); run $arg"</dev/null 2>&1| cat
echo"exit code: ${PIPESTATUS[0]}"done
Also seen on v1 1.18.35 (Linux, Fedora 44), so the problem is not only in v2:
$ opencode sessionsError: ENOENT: no such file or directory, chdir '/home/herlo/Projects/ethos/eiaio' -> 'sessions' at chdir (unknown) at <anonymous> (/$bunfs/root/chunk-yc1pse81.js:96:6419)
A common way to hit this is a near-miss subcommand: sessions instead of session. The positional [project] argument takes the typo, so the user gets a chdir error and no hint about the real command.
Suggestion for the fix: when the positional argument is not an existing directory and is close to a subcommand name, print something like:
Error: 'sessions' is not a command or an existing directory. Did you mean 'session'?
Run 'opencode --help' to see the commands.
Activity
1052326311 commentedon Sep 20, 2026
Reproduced on current v2 at eb0e26b with Bun 1.4.2 using an isolated CLI subprocess: the missing directory prints the chdir stack to stdout, with empty stderr. The exit status is already 1 on this head. I am preparing a narrow fix for the directory error output, with subprocess coverage for missing paths, file arguments, and a valid-directory control. This keeps the separate remote-directory routing change in #47818 out of scope.
lsilveirab39 commentedon Oct 21, 2026
Confirmed on v2.1.2 (current
latest) on Windows — the raw Bun stack is still leaked, and there are two additional details that seem worth adding to this report.Repro (Windows, opencode 2.1.2, npm
latest)Exit code
1. The message goes to stderr; stdout is empty (0 bytes).Observations beyond the original report
1. Behavior since 2.0.7 has partially changed, but the raw stack is still exposed. The original report observed exit
0with the stack on stdout and empty stderr. On 2.1.2 the exit code is1and the stack is on stderr. The internal frame (B:/~BUN/root/chunk-*.js) still reaches the user, so the underlying UX problem is unfixed — only the plumbing around it moved.2. Windows resolves the POSIX-style argument against the current drive root, and the error never shows the path actually attempted.
/pluginsis not treated as an opaque invalid path — on Windows it normalizes toC:\plugins, i.e. the root of the drive the shell is on (path.resolve('/plugins')→C:\plugins). The error message prints the un-normalized target ('/plugins') next to the resolved source, so the user never sees the path the process really tried, andC:\pluginslooks like a plausible system location rather than a typo.Confirmed identical for
/plugin,/nonexistent-dir-xyz, and any other/...value:3. The
/pluginsspelling is a genuine trap, and a targeted hint would fix this class of report.plugins.listin the TUI does declareslash: { name: "plugins" }(see #47345), so/pluginsis a valid TUI command. But it is also the natural thing to type in a shell, where it is silently consumed as the positional<directory>argument and produces this stack trace. A friendly error could special-case this:That single hint covers the whole
/mcps,/agents,/skills,/models,/themesfamily, and would have made this original report unnecessary in the first place.Environment
TERM=xterm-256color,TERM_PROGRAMunsetComSpec:cmd.exe)@opencode/cli@2.1.2), shared background serviceactive; MCP serversplaywright(local) andcontext7(remote)Reproduced consistently (3/3 for
/plugins, plus/pluginand/nonexistent-dir-xyz). No secrets included; paths redacted.opencodejr commentedon Oct 28, 2026
Thanks for the detailed report! I reproduced this on 2.0.7. From an empty directory,
opencode ls,opencode foobar123andopencode /nonexistent-dir-xyzeach print a rawENOENT: no such file or directory, chdir ... -> '<arg>'error with an internal stack frame, instead of a friendly "directory does not exist" message. It still happens on the latestdev(950111f). The CLI callschdiron the positional argument without checking it first.One difference: here the exit code was
1, not0, on both 2.0.7 anddev. If you still see0, could you check withopencode ls; echo $?directly in bash? A shell prompt or wrapper may be reporting something else.The script below reproduces it.
Reproduction script (repro.sh)
Run it:
bash repro.shherlo commentedon Nov 5, 2026
Also seen on v1 1.18.35 (Linux, Fedora 44), so the problem is not only in v2:
A common way to hit this is a near-miss subcommand:
sessionsinstead ofsession. The positional[project]argument takes the typo, so the user gets achdirerror and no hint about the real command.Suggestion for the fix: when the positional argument is not an existing directory and is close to a subcommand name, print something like: