jackwener/OpenCLI · warning
[opencli] Navigate to ${targetUrl} timed out after 15s
Error message
[opencli] Navigate to ${targetUrl} timed out after 15s What it means
A console warning from the navigation wait helper: when a target page's load/complete event does not fire within 15 seconds, the extension logs this, marks the wait as timed out, and proceeds (finish()) rather than hanging forever. The subsequent command may operate on a partially loaded page.
Source
Thrown at extension/src/background.ts:1799
finish();
}
};
chrome.tabs.onUpdated.addListener(listener);
// Also check if the tab already navigated (e.g. instant cache hit)
checkTimer = setTimeout(async () => {
try {
const currentTab = await chrome.tabs.get(tabId);
if (currentTab.status === 'complete' && isNavigationDone(currentTab.url)) {
finish();
}
} catch { /* tab gone */ }
}, 100);
// Timeout fallback with warning
timeoutTimer = setTimeout(() => {
timedOut = true;
console.warn(`[opencli] Navigate to ${targetUrl} timed out after 15s`);
finish();
}, 15000);
});
let tab = await chrome.tabs.get(tabId);
// Post-navigation drift detection: if the tab moved to another window
// during navigation (e.g. a tab-management extension regrouped it),
// try to move it back to maintain session isolation.
const postNavigationSession = automationSessions.get(leaseKey);
if (postNavigationSession && tab.windowId !== postNavigationSession.windowId) {
console.warn(`[opencli] Tab ${tabId} drifted to window ${tab.windowId} during navigation, moving back to ${postNavigationSession.windowId}`);
try {
await chrome.tabs.move(tabId, { windowId: postNavigationSession.windowId, index: -1 });
tab = await chrome.tabs.get(tabId);
} catch (moveErr) {
console.warn(`[opencli] Failed to recover drifted tab: ${moveErr}`);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command — transient network slowness often resolves
- Verify the target URL is reachable in a normal browser tab
- Check proxy/VPN/captive-portal state blocking page load
- Increase the navigation timeout in background.ts if 15s is too short for the target site
Example fix
// before
timeoutTimer = setTimeout(() => { ... finish(); }, 15000);
// after
timeoutTimer = setTimeout(() => { ... finish(); }, 30000); // tolerate slow sites Defensive patterns
Strategy: try-catch
Validate before calling
const reachable = await fetch(targetUrl, { method: 'HEAD', mode: 'no-cors', signal: AbortSignal.timeout(5000) }).then(r => r.ok).catch(() => false);
if (!reachable) warnUserBeforeNavigate(); Try / catch
const ok = await navigateAndWait(tabId, url, 15000).catch(() => false);
if (!ok) console.warn('page may be partially loaded'); Prevention
- Pre-check target URL reachability before navigating
- Raise the timeout for slow sites
- Ensure proxies/VPNs are not blocking the target
- Treat timed-out pages as possibly incomplete before asserting on content
When it happens
Trigger: chrome.tabs.update/get navigation to targetUrl where the load event never completes within 15000ms — slow site, hung network request, or a page whose lifecycle events don't map to the awaited condition.
Common situations: Slow or unresponsive target websites; captive portals or proxy auth prompts blocking load; SPAs with long-polling connections that keep the page 'loading'; offline/broken network during automation.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- coupang add-to-cart navigation failed: ${error?.message || e
- Discord did not finish navigating to the requested channel.
- Title page did not finish loading: ${id}
- LinkedIn people search navigation failed: ${error?.message |
- Failed to open Zhihu answer ${target.answerId}: ${error inst
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5b3f9fe366c1936e.
Report an issue: GitHub.