openclaw - ✅(Solved) Fix Feature: expose runtime headed browser start for human handoff without config restart [2 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#75879Fetched 2026-05-02 05:28:33
View on GitHub
Comments
2
Participants
3
Timeline
5
Reactions
2
Author
Timeline (top)
commented ×2cross-referenced ×2referenced ×1

Expose a first-class way to start an OpenClaw-managed browser profile in headed mode at runtime, matching the existing internal /start?headless=false route behavior.

Suggested public surfaces:

  • openclaw browser start --headed, or --headless=false
  • browser tool action="start" with headless: false or headed: true

Error Message

  1. Reject --headless --headed together with a clear CLI error.

Root Cause

Editing openclaw.json is not a good handoff mechanism because it can require Gateway reload/restart and affects broader browser configuration rather than just the immediate managed-browser launch.

Fix Action

Fixed

PR fix notes

PR #75880: feat(browser): add --headed flag to browser start for runtime headed handoff

Description (problem / solution / changelog)

Fixes #75879.

What changes

Exposes the existing POST /start?headless=false route via three public surfaces that previously only offered the headless direction:

1. CLI (--headed flag)

openclaw browser start --headed

Symmetric counterpart to --headless. Sends headless=false to the route for this start only, without touching config. --headed and --headless are mutually exclusive (error if both passed).

2. Browser tool (headed: true param)

{ "action": "start", "headed": true }

Added headed?: boolean to BrowserToolSchema. The tool derives headless = !headed and forwards it via query param on both the proxy-request path and the direct browserStart path.

3. browserStart client helper (headless opt) Added headless?: boolean to the browserStart opts so library callers can request the override without URL construction.

What does NOT change

  • Route parseHeadlessStartOverride — untouched; already handles ?headless=false correctly
  • Config-level browser.headless — not written; override applies to this start request only
  • Already-running browser — no-op (route behavior unchanged)
  • Attach-only / remote CDP / existing-session profiles — still reject the override (route rejects them)

Commit shape

3 commits, each independently testable:

  1. client.ts — headless opt on browserStart
  2. CLI + schema + browser-tool — end-to-end wiring
  3. Docs + CHANGELOG

Tests

pnpm test extensions/browser/src/cli/browser-cli-manage.timeout-option.test.ts \
          extensions/browser/src/browser/routes/basic.existing-session.test.ts \
          extensions/browser/src/browser/client.test.ts \
          extensions/browser/src/browser-tool.test.ts
# 72/72 passed
pnpm exec oxfmt --check --threads=1 <changed files>
# All matched files use the correct format.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • docs/cli/browser.md (modified, +6/-0)
  • docs/tools/browser-control.md (modified, +6/-2)
  • extensions/browser/src/browser-tool.schema.ts (modified, +1/-0)
  • extensions/browser/src/browser-tool.ts (modified, +11/-2)
  • extensions/browser/src/browser/client.ts (modified, +4/-2)
  • extensions/browser/src/cli/browser-cli-manage.ts (modified, +9/-2)

PR #75881: [codex] browser: expose headed start override

Description (problem / solution / changelog)

Summary

  • Add openclaw browser start --headed as the runtime counterpart to existing --headless.
  • Forward headless=false through the browser client and browser tool start action, including node proxy requests.
  • Add schema/tests for headless: false and headed: true start overrides, plus conflict handling.

Why

OpenClaw already supports request-local headless=false internally on /start, but the public CLI/tool surface could only force headless. Human handoff workflows need to stop the managed browser and restart the same profile headed without editing openclaw.json or restarting the Gateway.

Fixes #75879.

Validation

  • node scripts/run-vitest.mjs run --config test/vitest/vitest.unit.config.ts extensions/browser/src/cli/browser-cli-manage.timeout-option.test.ts extensions/browser/src/browser/client.test.ts extensions/browser/src/browser-tool.test.ts
  • pnpm tsgo:extensions:test
  • pnpm exec oxfmt --check extensions/browser/src/cli/browser-cli-examples.ts extensions/browser/src/cli/browser-cli-manage.ts extensions/browser/src/cli/browser-cli-manage.timeout-option.test.ts extensions/browser/src/browser/client.ts extensions/browser/src/browser/client.test.ts extensions/browser/src/browser-tool.schema.ts extensions/browser/src/browser-tool.ts extensions/browser/src/browser-tool.test.ts
  • git diff --check

Changed files

  • extensions/browser/src/browser-tool.schema.ts (modified, +2/-0)
  • extensions/browser/src/browser-tool.test.ts (modified, +40/-0)
  • extensions/browser/src/browser-tool.ts (modified, +27/-2)
  • extensions/browser/src/browser/client.test.ts (modified, +5/-0)
  • extensions/browser/src/browser/client.ts (modified, +9/-2)
  • extensions/browser/src/cli/browser-cli-examples.ts (modified, +1/-0)
  • extensions/browser/src/cli/browser-cli-manage.timeout-option.test.ts (modified, +26/-0)
  • extensions/browser/src/cli/browser-cli-manage.ts (modified, +16/-2)

Code Example

openclaw browser stop --browser-profile openclaw
openclaw browser start --browser-profile openclaw --headed

---

{ "action": "stop", "profile": "openclaw" }
{ "action": "start", "profile": "openclaw", "headless": false }
RAW_BUFFERClick to expand / collapse

Summary

Expose a first-class way to start an OpenClaw-managed browser profile in headed mode at runtime, matching the existing internal /start?headless=false route behavior.

Suggested public surfaces:

  • openclaw browser start --headed, or --headless=false
  • browser tool action="start" with headless: false or headed: true

Problem

For browser automation workflows, a practical human-handoff pattern is:

  1. Run the dedicated OpenClaw browser profile headless for normal unattended work.
  2. If the agent gets stuck, hits auth/2FA/CAPTCHA, or needs human judgment, stop the managed browser process.
  3. Restart the same profile in headed mode so the human can take over the visible browser window.
  4. After the human completes the step, reattach to the same profile/session and continue.

Today, the internals are close to supporting this, but the public CLI/tool surface is incomplete.

Current observations from installed OpenClaw 2026.4.29:

  • POST /start parses a headless query override and calls profileCtx.ensureBrowserAvailable({ headless }).
  • resolveManagedBrowserHeadlessMode() gives the request-level headlessOverride priority over config-derived headless mode.
  • stopRunningBrowser() stops the managed Chrome process without restarting the Gateway.
  • openclaw browser start exposes --headless, but not --headed or --headless=false.
  • The browser tool schema likewise does not appear to expose a headless: false start override.

This means users can force headless from the CLI, but cannot cleanly force headed at runtime without editing openclaw.json / browser.headless or using the lower-level HTTP route manually.

Editing openclaw.json is not a good handoff mechanism because it can require Gateway reload/restart and affects broader browser configuration rather than just the immediate managed-browser launch.

Expected behavior

Users should be able to perform a human handoff without mutating config:

openclaw browser stop --browser-profile openclaw
openclaw browser start --browser-profile openclaw --headed

Equivalent tool-level flow should also be possible:

{ "action": "stop", "profile": "openclaw" }
{ "action": "start", "profile": "openclaw", "headless": false }

The same dedicated profile should be reused so cookies/localStorage/auth state survive the handoff.

Important behavior note

headless / headed is a Chrome process launch property. If an existing managed Chrome process is already reachable, ensureBrowserAvailable() can return the existing process without relaunching it. So switching from headless to headed requires stopping the managed browser process first, then starting it again with headless=false.

This is fine, but the public UX should make it clear. Possible options:

  • document stop -> start --headed as the intended handoff sequence
  • optionally add a --restart / --replace flag later, but that is not required for the minimal fix

Non-goals

  • Do not require editing openclaw.json.
  • Do not require restarting the Gateway.
  • Do not attempt to mutate headless/headed mode on a running Chrome process.
  • Do not apply this override to incompatible modes such as remote CDP / attach-only / existing-session if those are intentionally rejected today.

Related work

  • #37125 / PR #69228: per-profile headless config override. Useful, but config-level rather than runtime handoff.
  • PR #45207: added openclaw browser start --headless and request-level headless override. This issue asks for the symmetric headed runtime override to be exposed.
  • #64464 / #64317: headed environment/display issues. Related operationally, but not the same feature gap.

Implementation sketch

Small-scope change:

  1. Add --headed to openclaw browser start.
  2. Pass query: { headless: false } to /start when --headed is set.
  3. Reject --headless --headed together with a clear CLI error.
  4. Add the same boolean surface to the browser tool start action, if applicable.
  5. Add tests for:
    • --headless sends headless=true
    • --headed sends headless=false
    • no flag sends no override
    • conflicting flags fail clearly

User impact

This enables unattended browser automation that can fall back to a human-visible browser window for login/2FA/CAPTCHA/manual judgment, while keeping the Gateway alive and preserving the dedicated profile state.

extent analysis

TL;DR

To enable a human handoff in OpenClaw-managed browser profiles, add a --headed flag to the openclaw browser start command and pass headless: false to the /start route.

Guidance

  • Add a --headed flag to openclaw browser start to allow users to start a browser profile in headed mode.
  • Pass query: { headless: false } to the /start route when --headed is set to ensure the browser starts in headed mode.
  • Update the browser tool schema to include a headless: false or headed: true start override for consistency.
  • Test the new functionality to ensure it works as expected, including error handling for conflicting flags.

Example

openclaw browser stop --browser-profile openclaw
openclaw browser start --browser-profile openclaw --headed

This example demonstrates the intended handoff sequence, stopping the managed browser process and then starting it again in headed mode.

Notes

The implementation should not require editing openclaw.json or restarting the Gateway, and should preserve the dedicated profile state.

Recommendation

Apply the workaround by adding the --headed flag to openclaw browser start and updating the browser tool schema, as this provides a clear and consistent way to start a browser profile in headed mode at runtime.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Users should be able to perform a human handoff without mutating config:

openclaw browser stop --browser-profile openclaw
openclaw browser start --browser-profile openclaw --headed

Equivalent tool-level flow should also be possible:

{ "action": "stop", "profile": "openclaw" }
{ "action": "start", "profile": "openclaw", "headless": false }

The same dedicated profile should be reused so cookies/localStorage/auth state survive the handoff.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Feature: expose runtime headed browser start for human handoff without config restart [2 pull requests, 2 comments, 3 participants]