8000 `wmux browser` / `agent` / `pane` with no subcommand print "Unknown ... command: undefined" instead of usage · Issue #156 · amirlehmam/wmux · GitHub
[go: up one dir, main page]

Skip to content

wmux browser / agent / pane with no subcommand print "Unknown ... command: undefined" instead of usage #156

Closed

Description

@capad-xyz

Summary

Running a group command with no subcommand prints the literal word undefined instead of that command's usage. Three dispatchers do this; two others in the same file already do the right thing.

$ wmux browser
Unknown browser command: undefined      (exit 1)

$ wmux agent
Unknown agent command: undefined        (exit 1)

$ wmux pane
Unknown pane subcommand: undefined      (exit 1)

versus, in the same CLI:

$ wmux markdown
Usage: wmux markdown <file>  |  wmux markdown set <id> --content <text> [--title T] | --file <path>  |  wmux markdown get <id>

$ wmux config
Usage: wmux config <show|reload|path>

Verified on v0.46.0. Exit status is 1 in all five cases, so only the message differs.

Cause

Each of the three interpolates args[1] into the error without checking that it exists, so a missing subcommand is reported as an unknown one named undefined:

wmux/src/cli/wmux.ts

Lines 143 to 147 in fae21a5

async function cmdBrowser(args: string[]): Promise<void> {
const handler = BROWSER_CMDS[args[1]];
if (!handler) { console.error(`Unknown browser command: ${args[1]}`); process.exit(1); return; }
print(await handler(args));
}

wmux/src/cli/wmux.ts

Lines 184 to 188 in fae21a5

async function cmdAgent(args: string[]): Promise<void> {
const handler = AGENT_CMDS[args[1]];
if (!handler) { console.error(`Unknown agent command: ${args[1]}`); process.exit(1); return; }
print(await handler(args));
}

wmux/src/cli/wmux.ts

Lines 204 to 206 in fae21a5

} else {
console.error(`Unknown pane subcommand: ${sub}`); process.exit(1);
}

COMMAND_SPECS already carries the usage string these should fall back to, and fail() already exists to print it — which is how markdown and config get it right. wmux browser --help cannot fill the gap either, since browser is passthrough: true and --help is treated as text to send.

Why it is worth fixing

wmux browser on its own is the natural thing to type when you want to know the verbs. Getting undefined back reads like the CLI malfunctioned rather than like a usage error, and it is a dead end: nothing in the output points at wmux help browser, which is the route that does work.

Small, but it is the first thing a new user or a fresh agent hits when exploring the browser API.

Note

cmdBrowser is the same function touched by #153, so if you would rather this land there than as a separate change, say the word and I will fold it in — I kept it out to avoid widening the scope of a PR you had not looked at yet.

Activity

  1. amirlehmam commented on Aug 13, 2026

    @amirlehmam
    Owner

    Fixed in 0.50.0, separately from #153 as you offered — a usage-message change riding inside a timeout fix would have made both harder to read.

    Taken across all four dispatchers, not three: cmdLayout had the same shape (Unknown layout command: ${args[1]}), so a bare wmux layout printed undefined too.

    $ wmux browser
    wmux browser needs a subcommand.
    
    wmux browser open <url> | snapshot | click <ref> | type <ref> <text> | fill <ref> <value>
    wmux browser screenshot [--full] | get-text [ref] | eval <js> | wait <ref> [ms]
    wmux browser back | forward | reload
      [--surface <id>]   (surface defaults to $WMUX_SURFACE_ID inside a pane)
    
    $ wmux browser opne
    Unknown browser subcommand: opne
    <same usage>
    

    Both go through fail(), so a typo'd verb gets the verb list too — it was equally a dead end before, just a less common one. Exit status stays 1 everywhere.

    The interesting bit is the guard rather than the fix. failSubcommand(command: CommandName, …) is typed against COMMAND_SPECS, so "this group command has usage text to print" is now a compile-time property rather than something a test has to remember to check — the same trick that already stops a command shipping without usage. And tests/unit/cli-subcommands.test.ts scans the CLI source for the shape of the bug (console.error(\Unknown …: ${args[1]}`)`) rather than enumerating the four known sites, so a fifth group command added next year fails the test instead of shipping the same dead end.

    You called this "small, but it is the first thing a new user or a fresh agent hits when exploring the browser API" — that's exactly why it was worth its own issue. undefined in a CLI's own error message reads like a crash, and an agent that reads it has no reason to try wmux help browser next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0