jackwener/OpenCLI · error · Error
attach failed: ${lastError}${hint}
Error message
attach failed: ${lastError}${hint} What it means
ensureAttached calls chrome.debugger.attach and, on failure, logs the URL/windowId context and throws 'attach failed: <lastError>'. If the error mentions chrome-extension://, a hint is appended suggesting another extension is interfering, since only one debugger client may attach per tab.
Source
Thrown at extension/src/cdp.ts:201
}
}
}
if (lastError) {
// Log detailed diagnostics for debugging extension conflicts
let finalUrl = 'unknown';
let finalWindowId = 'unknown';
try {
const tab = await chrome.tabs.get(tabId);
finalUrl = tab.url ?? 'undefined';
finalWindowId = String(tab.windowId);
} catch { /* tab gone */ }
console.warn(`[opencli] attach failed for tab ${tabId}: url=${finalUrl}, windowId=${finalWindowId}, error=${lastError}`);
const hint = lastError.includes('chrome-extension://')
? '. Tip: another Chrome extension may be interfering — try disabling other extensions'
: '';
throw new Error(`attach failed: ${lastError}${hint}`);
}
attached.add(tabId);
try {
await sendDebuggerCommand({ tabId }, 'Runtime.enable');
} catch {
// Some pages may not need explicit enable
}
// Restore network capture that the re-attach (detach + onDetach) tore down.
// The detach always disables the CDP Network domain, so re-enable it and put
// the accumulated capture state back unconditionally. Done last (after the
// awaits above) so it wins over the onDetach handler's delete, which fires
// while those awaits yield to the event loop.
if (preservedNetworkCapture) {
try {
await sendDebuggerCommand({ tabId }, 'Network.enable');
networkCaptures.set(tabId, preservedNetworkCapture);View on GitHub (pinned to 49907e53dc)
Solutions
- Close DevTools for the target tab and retry
- Disable other Chrome extensions that use chrome.debugger, as the hint suggests
- Retry the command — transient races (tab mid-navigation) often succeed on a second attempt
- Check lastError details; if it says 'Another debugger already attached', find the conflicting client
Example fix
// before attach failed: Another debugger is already attached to the tab // after // close DevTools / disable conflicting extension, then retry attach
Defensive patterns
Strategy: retry
Validate before calling
// cannot pre-check attach exclusivity; mitigate by closing DevTools and other debugger clients first
const dbg = await new Promise(r => chrome.debugger.getTargets(ts => r(ts.filter(t => t.tabId === tabId && t.attached))));
if (dbg.length) throw new Error('another debugger already attached'); Type guard
function isAlreadyAttachedError(msg: string): boolean {
return /already attached|Another debugger/i.test(msg);
} Try / catch
try {
await cdp.ensureAttached(tabId);
} catch (e) {
const m = (e as Error).message;
if (m.startsWith('attach failed')) {
if (isAlreadyAttachedError(m)) closeDevToolsOrConflictingExtension();
await sleep(300); return retry();
}
throw e;
} Prevention
- Don't keep DevTools open on tabs under automation
- Disable recorder/other chrome.debugger extensions during runs
- Retry attach after short backoff — races are common during navigation
- Read the appended hint; chrome-extension:// mentions point to extension conflicts
When it happens
Trigger: chrome.debugger.attach rejects in ensureAttached — target closed mid-attach, another debugger/DevTools already attached, permission canceled by the user, or cross-extension contention.
Common situations: DevTools is open on the same tab (Chrome allows only one debugger); another automation extension (e.g. recording tools) holds the debugger; the tab navigated/closed during attach; user dismissed the 'started debugging' infobar permission.
Related errors
- Bound tab for session "${session.session}" is not debuggable
- bound_tab_not_debuggable
- Cannot debug tab ${tabId}: URL is ${tab.url ?? 'unknown'}
- Tab ${tabId} no longer exists
- No iframe target found for frame ${frameId}${targetUrl ? ` (
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/87b77025c2b829c3.
Report an issue: GitHub.