The image that never loaded
One image whose server never answered held every script-based call an agent made in its tab. The cause is a wait inside Electron; the fix is to wait for the document, not for the whole page.
On October 22, 2026, an agent in Hronaut sat on “Running a script on the page” for minutes. The page looked finished. One image on it was not: its server had accepted the request and never answered.
The symptom
Every agent call that runs a script in the page waited until the agent's request timed out: reading the page (browser_snapshot), clicking (browser_click), running code (browser_evaluate). The workspace stayed busy for the agent's next calls, and the tab kept showing the agent at work.
The cause
Hronaut runs its page scripts through Electron's webContents.executeJavaScript. While the main frame is loading, Electron does not run the script. It waits:
const waitTillCanExecuteJavaScript = async (webContents) => {
if (webContents.getURL() && !webContents.isLoadingMainFrame()) return;
return new Promise((resolve) => {
webContents.once('did-stop-loading', () => { resolve(); });
});
};
did-stop-loading fires when the tab's loading spinner stops. An image that never answers keeps the spinner going, so the script never starts. The DevTools console doesn't wait like this: it runs your code as soon as the document is there.
The fix
Hronaut now decides when a page script may run. A script runs once the shown document is ready (its DOMContentLoaded), as in DevTools, while images and other resources keep loading. Navigating and waking a sleeping tab go on after 30 seconds while the page keeps loading, as in Chrome. A page that has shown nothing after 30 seconds gets a plain error, “Timed out waiting for the page to finish loading”, instead of a request that hangs.
One more trap turned up on the way. A navigation that ends with a 204 response or a download fires no event that says it ended, so Hronaut gives the new document three seconds to appear after the request ends, then treats the old page as current again.
The fix shipped in Hronaut 3.5.0, on October 22, 2026.
What to take from it
If you build agent tools on Electron or another embedded browser, “the page finished loading” is the wrong gate for page scripts. Long polling, a stalled CDN, an analytics beacon: real pages often never finish. Gate on the document, cap every wait, and tell the agent what happened instead of letting its request time out.
Sources: Electron, lib/browser/api/web-contents.ts (waitTillCanExecuteJavaScript), Electron docs: did-stop-loading, Hronaut changelog, 3.5.0, Hronaut source: page-script-readiness.ts, pull request #1186.
Written with the help of AI.