{"record":{"id":"330dca9e6d62f031","repo":"jackwener/OpenCLI","slug":"opencli-tab-tabid-no-longer-exists-re-resolv","errorCode":null,"errorMessage":"[opencli] Tab ${tabId} no longer exists, re-resolving","messagePattern":"\\[opencli\\] Tab (.+?) no longer exists, re-resolving","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"extension/src/background.ts","lineNumber":1526,"sourceCode":"            return { tabId, tab: moved };\n          }\n        } catch (moveErr) {\n          console.warn(`[opencli] Failed to move tab back: ${moveErr}`);\n        }\n      } else if (!isDebuggableUrl(tab.url)) {\n        console.warn(`[opencli] Tab ${tabId} URL is not debuggable (${tab.url}), re-resolving`);\n      }\n    } catch (err) {\n      if (err instanceof CommandFailure) throw err;\n      if (existingSession && !existingSession.owned) {\n        automationSessions.delete(leaseKey);\n        throw new CommandFailure(\n          'bound_tab_gone',\n          `Bound tab for session \"${existingSession.session}\" no longer exists.`,\n          'Run \"opencli browser bind\" again, then retry the command.',\n        );\n      }\n      console.warn(`[opencli] Tab ${tabId} no longer exists, re-resolving`);\n    }\n  }\n\n  const existingPreferredTabId = existingSession?.preferredTabId ?? null;\n  if (existingSession && existingPreferredTabId !== null) {\n    const session = existingSession;\n    try {\n      const preferredTab = await chrome.tabs.get(existingPreferredTabId);\n      if (isDebuggableUrl(preferredTab.url)) return { tabId: preferredTab.id!, tab: preferredTab };\n      if (!session.owned) {\n        throw new CommandFailure(\n          'bound_tab_not_debuggable',\n          `Bound tab for session \"${session.session}\" is not debuggable (${preferredTab.url ?? 'unknown URL'}).`,\n          'Switch the tab to an http(s) page or run \"opencli browser bind\" on another tab.',\n        );\n      }\n    } catch (err) {\n      if (err instanceof CommandFailure) throw err;","sourceCodeStart":1508,"sourceCodeEnd":1544,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/extension/src/background.ts#L1508-L1544","documentation":"A console warning logged when the previously bound tab id can no longer be fetched (chrome.tabs.get rejects) — the tab was closed. If an owned session depended on it, a CommandFailure 'bound_tab_gone' is thrown with remediation advice; otherwise the extension just re-resolves a new tab.","triggerScenarios":"User (or a script) closes the bound tab between commands; a window containing the tab is closed; Chrome crashes and restores without the tab.","commonSituations":"Manual cleanup of browser tabs during long automation sessions; closing windows at end of day; tab crash ('Aw, Snap') removing the tab.","solutions":["Run 'opencli browser bind' again on a debuggable http(s) tab, then retry the command","Re-run the failing command — re-resolution will pick or create a replacement tab","Keep the automation window/tab open while commands are running","Use a dedicated browser window for automation to avoid accidental closure"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const exists = await chrome.tabs.get(tabId).then(() => true).catch(() => false);\nif (!exists) await opencliBrowserBind();","typeGuard":null,"tryCatchPattern":"try { await runBoundCommand(); } catch (e) { if (e.code === 'bound_tab_gone') { await bind(); await runBoundCommand(); } else throw e; }","preventionTips":["Keep the bound tab open for the session duration","Use a dedicated automation window","Handle bound_tab_gone by rebinding and retrying"],"tags":["chrome-extension","tab-management","automation"],"backgroundTag":"bound-tab-closed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}