{"record":{"id":"50922cd2329e91c1","repo":"different-ai/openwork","slug":"could-not-resolve-built-in-browser-cdp-target","errorCode":null,"errorMessage":"Could not resolve built-in browser CDP target.","messagePattern":"Could not resolve built-in browser CDP target\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/browser-panel.mjs","lineNumber":147,"sourceCode":"    const targets = await response.json();\n    return Array.isArray(targets) ? targets : [];\n  }\n\n  async function resolveBrowserCdpTargetId(tabId) {\n    const marker = encodeURIComponent(`openwork-browser-tab:${tabId}`);\n    const deadline = Date.now() + BROWSER_TARGET_RESOLVE_TIMEOUT_MS;\n    while (Date.now() < deadline) {\n      const targets = await listCdpTargets().catch(() => []);\n      const target = targets.find((candidate) => (\n        candidate?.type === \"page\" &&\n        typeof candidate.id === \"string\" &&\n        typeof candidate.url === \"string\" &&\n        candidate.url.includes(marker)\n      ));\n      if (target?.id) return target.id;\n      await new Promise((resolve) => setTimeout(resolve, BROWSER_TARGET_RESOLVE_INTERVAL_MS));\n    }\n    throw new Error(\"Could not resolve built-in browser CDP target.\");\n  }\n\n  async function openBrowserUrlForAutomation(rawUrl, provider = \"auto\") {\n    const requestedProvider = String(provider || \"auto\").trim().toLowerCase();\n    if (requestedProvider && requestedProvider !== \"auto\" && requestedProvider !== \"builtin\") {\n      throw new Error(`Browser provider is not available yet: ${requestedProvider}`);\n    }\n    const url = normalizeBrowserUrl(rawUrl);\n    const tab = createBrowserTab(\"about:blank\", { select: true });\n    await tab.view.webContents.loadURL(browserTargetMarkerUrl(tab.tabId));\n    const targetId = await resolveBrowserCdpTargetId(tab.tabId);\n    await tab.view.webContents.loadURL(url);\n    return {\n      provider: \"builtin\",\n      browser_url: cdpBrowserUrl(),\n      target_id: targetId,\n      tab_id: tab.tabId,\n      url,","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/browser-panel.mjs#L129-L165","documentation":"resolveBrowserCdpTargetId polls the app's CDP target list for a target whose URL contains the built-in browser tab's marker URL, up to a fixed timeout. If no matching target appears before the polling loop exhausts, it throws this error, meaning the automation layer cannot attach to the built-in browser view via Chrome DevTools Protocol.","triggerScenarios":"Calling openBrowserUrlForAutomation (or resolveBrowserCdpTargetId directly) when the WebContentsView for the tab has not finished creating/registered a CDP target with the marker URL in browserTargetMarkerUrl(tabId), or the polling interval x attempts elapses before the target appears.","commonSituations":"Slow machine or heavy load delaying target registration; the built-in browser view failed to attach to CDP; Electron/CDP debugging not enabled for that session; navigating away from the marker page before the target resolves; a race where the tab was closed mid-resolution.","solutions":["Retry the automation call — the target may register shortly after the timeout","Check that the built-in browser tab still exists and its webContents loaded the marker URL successfully","Ensure CDP/debugging is available for the Electron session (no flags disabling remote debugging)","Increase BROWSER_TARGET_RESOLVE_INTERVAL_MS / poll attempts if targets register slowly on the target hardware"],"exampleFix":"// before\nconst targetId = await resolveBrowserCdpTargetId(tab.tabId);\n// after\nlet targetId;\ntry { targetId = await resolveBrowserCdpTargetId(tab.tabId); }\ncatch { await tab.view.webContents.loadURL(browserTargetMarkerUrl(tab.tabId)); targetId = await resolveBrowserCdpTargetId(tab.tabId); }","handlingStrategy":"retry","validationCode":"const tabs = listBrowserTabs();\nif (!tabs.some(t => String(t.tabId) === String(tabId))) throw new Error(`tab ${tabId} is not open`);","typeGuard":"function isResolvedTargetId(v) { return typeof v === 'string' && v.length > 0; }","tryCatchPattern":"try {\n  const targetId = await resolveBrowserCdpTargetId(tabId);\n} catch (e) {\n  if (e.message.includes('Could not resolve built-in browser CDP target')) {\n    // wait and retry once, or surface a 'browser not ready' state\n  } else throw e;\n}","preventionTips":["Retry with backoff around automation calls","Confirm the tab loaded its marker URL before resolving the CDP target","Keep the tab alive for the duration of resolution (don't close mid-poll)","Monitor app logs for CDP target registration delays on slow machines"],"tags":["cdp","electron","browser-automation","timeout"],"backgroundTag":"cdp-target-not-found","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}