#2121

back/forward report "Inspected target navigated or closed" after the navigation succeeded

Openctamulonis-glossyopened 15d ago

agent-browser back (and, by the same code, forward) can return an error even though the navigation succeeded:

$ agent-browser --json back
{"success":false,"error":"CDP error (Runtime.evaluate): Inspected target navigated or closed"}
$ agent-browser get url
http://localhost:8931/          # the previous page — the back navigation happened

It is intermittent. On macOS with Chrome for Testing it failed 3 of 3 times against pages served by python3 -m http.server, and only sometimes against a small Node http server.

Reproduce

mkdir /tmp/ab-back && cd /tmp/ab-back
echo '<a href="two.html">two</a>' > index.html
echo '<p>two</p>' > two.html
python3 -m http.server 8931 &

agent-browser open http://localhost:8931/
agent-browser open http://localhost:8931/two.html
agent-browser --json back      # often: success:false, "Inspected target navigated or closed"
agent-browser get url          # http://localhost:8931/

Seen on agent-browser 0.39.1; the code path is unchanged on main (dac13bb).

Cause

handle_back in cli/src/native/actions.rs (~L6826 on main) runs

mgr.evaluate("history.back()", None).await?;
tokio::time::sleep(Duration::from_millis(500)).await;
let url = mgr.get_url().await.unwrap_or_default();

and waits for the Runtime.evaluate reply. The navigation history.back() starts tears down the execution context, so the reply can arrive as "Inspected target navigated or closed". The ? propagates it, and the sleep/get_url that would report the new page never run. handle_forward (~L6845) is identical. The race is plausibly lost more often when the previous page is restored from the back/forward cache, but that is a guess.

Suggested fix

Either of:

  • Navigate through CDP history instead of page script: Page.getNavigationHistory, then Page.navigateToHistoryEntry with the previous/next entry id. That does not depend on the page's execution context surviving.
  • Or treat "Inspected target navigated or closed" from this specific evaluate as success and continue to the existing wait and get_url.

Environment

  • agent-browser 0.39.1 (native CLI), Chrome for Testing, macOS
  • Pages served by python3 -m http.server (fails consistently) and a Node http server (fails sometimes)

Activity

3
naeemgwendlyn2615d ago

Since the execution context is destroyed during history navigation, we should wrap the mgr.evaluate call in a try-catch block to ignore the "Inspected target navigated or closed" error, then rely solely on the subsequent URL check to confirm the operation succeeded.

akushonkamen14d ago

Confirmed the root cause: in cli/src/native/actions.rs on main, both handle_back (~L6826) and handle_forward (~L6845) do mgr.evaluate("history.back()", None).await? / mgr.evaluate("history.forward()", None).await? — the ? propagates the Inspected target navigated or closed CDP error that arrives when the navigation started by the script tears down the execution context, so the following sleep + get_url (which would report the new URL) never run even though the navigation succeeded.

I'm working on a fix (treat that specific error from this evaluate call as success and continue to the existing wait + URL read, keeping the change scoped to these two call sites). Will open a PR shortly — happy to consider the Page.getNavigationHistory/navigateToHistoryEntry approach if maintainers prefer it.

NOTE

This comment and the upcoming PR are authored with AI assistance (Claude, an AI coding agent), under human review.

akushonkamen14d ago

The fix is up as #2129. It goes with the Page.getNavigationHistory/Page.navigateToHistoryEntry approach (browser-side, so the navigation can't destroy the execution context the command depends on), with a narrowed fallback to the page-script evaluation for engines without those commands. Full root cause, test evidence, and the three new mock-CDP regression tests are in the PR description.