Skip to content

@playwright/cli crashes with a raw Node stack trace on any input error (and prints no JSON with --json) #502

Closed

Description

playwright-cli.js calls program({ embedderVersion }) without awaiting it or attaching a .catch. The core's own entry, playwright-core/lib/tools/cli-client/cli.js, does program().catch(e => { console.error(e.message); processExit(1); }). So every error thrown by program() becomes an unhandled rejection in @playwright/cli.

Steps to reproduce

playwright-cli open https://example.com
playwright-cli open --headed=false
playwright-cli screenshot --filename
playwright-cli --json screenshot --filename > out.json   # exit 1, out.json is empty

Actual

/…/playwright-core/lib/tools/cli-client/minimist.js:56
        throw new Error(`boolean option '--${key}' should not be passed with '=value', ...`);
              ^
Error: boolean option '--headed' should not be passed with '=value', use '--headed' or '--no-headed' instead
    at minimist (…)

Same for daemon start failures and daemon-side validation errors ('--filename' option: expected string, received boolean). With --json, stdout is empty while normal tool errors return {"isError": true, "error": "…"}, so agents that parse JSON get nothing usable.

Expected

A one-line error message and exit code 1, like node playwright-core/lib/tools/cli-client/cli.js open --headed=false prints; and a JSON error object in --json mode.

Suggested fix

async function main() {
  await checkForUpdates().catch(() => {});
  await program({ embedderVersion: packageJson.version }).catch(e => {
    console.error(e.message);
    process.exit(1);
  });
}

(Separately: a string flag given without a value, e.g. --filename, is parsed as true and only rejected by the daemon; it could be rejected client-side with the command's help.)

Environment

  • @playwright/cli 0.1.23 (main @ f50f579), playwright-core 1.65.0-alpha-2026-10-30
  • Node 22.23.4, Linux x64, Chrome for Testing 153

Activity

  1. github-actions commented on Nov 5, 2026

    @github-actions
  2. microsoft-playwright-automation commented on Nov 5, 2026

    @microsoft-playwright-automation
    Contributor

    Hi, I'm the Playwright bot and I reproduced this on Linux.

    Reproduced with @playwright/cli 0.1.23 (playwright-core 1.65.0-alpha-2026-10-30). The package entry point does not await or catch program() failures. The proposed fix handles those failures, prints only the error message in text mode, and returns { "isError": true, "error": "..." } on stdout with --json, with exit code 1.

    Reproduction and verification

    On Linux with Node 24.22.2, at commit 2cbc57d186eb8a70e64ebbd6c923741100c69a9e:

    playwright-cli open --headed=false
    playwright-cli --json open --headed=false
    playwright-cli open 'data:text/html,hello' --persistent
    playwright-cli --json screenshot --filename
    playwright-cli delete-data

    Before the fix, the malformed boolean argument printed a raw Node stack trace; JSON mode produced empty stdout. The regression test now verifies the exact text/JSON output and exit status, including daemon-side screenshot argument validation with Chrome.

    All nine integration tests passed with npm test. Additional checks passed for --json/--no-json overrides, explicit --json true/--json false, and JSON output for an asynchronous missing-config startup error. The native upstream entry point at edeb0bd05176ff187c372c1e38e5d89a232bd5b3 already catches text-mode failures; this fix belongs in this package's wrapper. These checks cover CLI error handling rather than browser-specific behavior.

    Draft PR: #522

    Triaged on Linux by the Playwright bot - agent run

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions