Skip to content

cli: invalid directory arg shows raw ENOENT chdir stack trace instead of friendly error #49663

Open

Description

@sarniva

Summary

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.

Environment

  • opencode version: 2.0.7
  • OS: Linux arch 6.18.49-3-lts feat: compact and other improvements #1 SMP PREEMPT_DYNAMIC Sun, 06 Sep 2026 13:22:39 +0000 x86_64 GNU/Linux
  • Terminal: TERM=xterm-256color, COLORTERM=truecolor, TERM_PROGRAM=unset
  • Shell: /bin/bash
  • 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

  1. Open a shell in a directory without a ./ls entry (e.g. ~).
  2. Run opencode ls.
  3. Observe the error output.
  4. 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.

Additional Context

  • Consistently reproducible (3/3 tries: ls, foobar123, /nonexistent-dir-xyz).
  • opencode --help lists subcommands: upgrade, uninstall, acp, api, debug, auth, mcp, plugin, models, stats, mini, run, session, service, reload, pair, serve.
  • Workaround: run opencode --help to check valid subcommands; pass only existing directories as positional arg.
  • No secrets included; MCP API keys redacted from config.

Activity

  1. 1052326311 commented on Sep 20, 2026

    @1052326311
    Contributor

    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.

  2. lsilveirab39 commented on Oct 21, 2026

    @lsilveirab39

    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 /plugins
    Error: 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 /plugin
    Error: 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.

  3. opencodejr commented on Oct 28, 2026

    @opencodejr

    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)"
    for arg in ls foobar123 /nonexistent-dir-xyz; do
      echo "--- opencode $arg"
      timeout 30 bash -c "$(declare -f run); run $arg" </dev/null 2>&1 | cat
      echo "exit code: ${PIPESTATUS[0]}"
    done

    Run it: bash repro.sh

  4. herlo commented on Nov 5, 2026

    @herlo

    Also seen on v1 1.18.35 (Linux, Fedora 44), so the problem is not only in v2:

    $ opencode sessions
    Error: 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.
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions