Skip to content

close_tab() on the current tab leaves dangling session state #379

@sauravpanda

Description

@sauravpanda

Context

Follow-up from #337, which added close_tab(target=None) to src/browser_harness/helpers.py. Merged with this known sharp edge.

Problem

switch_tab() registers the active tab/session in the daemon via:

_send({"meta": "set_session", "session_id": sid, "target_id": target_id})

close_tab() calls Target.closeTarget directly and does not clear or update that state. So when you call close_tab() with no args (closing the currently-attached tab), the daemon still believes that now-dead targetId / sessionId is active.

Subsequent calls that depend on the attached session — js(), page_info(), current_tab(), _mark_tab(), etc. — will hit a dead session and fail or misbehave until the caller manually switch_tab()s to another tab.

The bulk-cleanup example in the PR description sidesteps this by only closing non-current tabs, but the no-arg close_tab() shape is the obvious footgun.

Repro

new_tab("https://example.com")
close_tab()           # closes the attached tab
page_info()           # boom — session points at a closed target

Suggested fix

When close_tab() is closing the currently-attached tab, fall back to another real tab before issuing Target.closeTarget:

  • If list_tabs(include_chrome=False) has another tab, switch_tab() to it first, then close the old targetId.
  • If no other real tab exists, either (a) open a fresh about:blank and switch to it, or (b) clear the daemon session and document that the caller must switch_tab() / new_tab() before further calls.

Option (a) matches the spirit of ensure_real_tab() and keeps the harness in a usable state. Option (b) is simpler but pushes the burden onto callers.

Either way, add a short note to the docstring.

Scope

  • src/browser_harness/helpers.py — update close_tab().
  • Worth a small test: open two tabs, close current, assert that subsequent current_tab() / js() works.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions