{"record":{"id":"87b77025c2b829c3","repo":"jackwener/OpenCLI","slug":"attach-failed-lasterror-hint","errorCode":null,"errorMessage":"attach failed: ${lastError}${hint}","messagePattern":"attach failed: (.+?)(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extension/src/cdp.ts","lineNumber":201,"sourceCode":"      }\n    }\n  }\n\n  if (lastError) {\n    // Log detailed diagnostics for debugging extension conflicts\n    let finalUrl = 'unknown';\n    let finalWindowId = 'unknown';\n    try {\n      const tab = await chrome.tabs.get(tabId);\n      finalUrl = tab.url ?? 'undefined';\n      finalWindowId = String(tab.windowId);\n    } catch { /* tab gone */ }\n    console.warn(`[opencli] attach failed for tab ${tabId}: url=${finalUrl}, windowId=${finalWindowId}, error=${lastError}`);\n\n    const hint = lastError.includes('chrome-extension://')\n      ? '. Tip: another Chrome extension may be interfering — try disabling other extensions'\n      : '';\n    throw new Error(`attach failed: ${lastError}${hint}`);\n  }\n  attached.add(tabId);\n\n  try {\n    await sendDebuggerCommand({ tabId }, 'Runtime.enable');\n  } catch {\n    // Some pages may not need explicit enable\n  }\n\n  // Restore network capture that the re-attach (detach + onDetach) tore down.\n  // The detach always disables the CDP Network domain, so re-enable it and put\n  // the accumulated capture state back unconditionally. Done last (after the\n  // awaits above) so it wins over the onDetach handler's delete, which fires\n  // while those awaits yield to the event loop.\n  if (preservedNetworkCapture) {\n    try {\n      await sendDebuggerCommand({ tabId }, 'Network.enable');\n      networkCaptures.set(tabId, preservedNetworkCapture);","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/extension/src/cdp.ts#L183-L219","documentation":"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.","triggerScenarios":"chrome.debugger.attach rejects in ensureAttached — target closed mid-attach, another debugger/DevTools already attached, permission canceled by the user, or cross-extension contention.","commonSituations":"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.","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"],"exampleFix":"// before\nattach failed: Another debugger is already attached to the tab\n// after\n// close DevTools / disable conflicting extension, then retry attach","handlingStrategy":"retry","validationCode":"// cannot pre-check attach exclusivity; mitigate by closing DevTools and other debugger clients first\nconst dbg = await new Promise(r => chrome.debugger.getTargets(ts => r(ts.filter(t => t.tabId === tabId && t.attached))));\nif (dbg.length) throw new Error('another debugger already attached');","typeGuard":"function isAlreadyAttachedError(msg: string): boolean {\n  return /already attached|Another debugger/i.test(msg);\n}","tryCatchPattern":"try {\n  await cdp.ensureAttached(tabId);\n} catch (e) {\n  const m = (e as Error).message;\n  if (m.startsWith('attach failed')) {\n    if (isAlreadyAttachedError(m)) closeDevToolsOrConflictingExtension();\n    await sleep(300); return retry();\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["cdp","debugger-attach","chrome-extension","devtools-conflict"],"backgroundTag":"debugger-already-attached","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}