{"record":{"id":"15c07d75f9065c7d","repo":"jackwener/OpenCLI","slug":"opencli-tab-tabid-drifted-to-window-tab-win-15c07d","errorCode":null,"errorMessage":"[opencli] Tab ${tabId} drifted to window ${tab.windowId} during navigation, moving back to ${postNavigationSession.windowId}","messagePattern":"\\[opencli\\] Tab (.+?) drifted to window (.+?) during navigation, moving back to (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"extension/src/background.ts","lineNumber":1811,"sourceCode":"      } catch { /* tab gone */ }\n    }, 100);\n\n    // Timeout fallback with warning\n    timeoutTimer = setTimeout(() => {\n      timedOut = true;\n      console.warn(`[opencli] Navigate to ${targetUrl} timed out after 15s`);\n      finish();\n    }, 15000);\n  });\n\n  let tab = await chrome.tabs.get(tabId);\n\n  // Post-navigation drift detection: if the tab moved to another window\n  // during navigation (e.g. a tab-management extension regrouped it),\n  // try to move it back to maintain session isolation.\n  const postNavigationSession = automationSessions.get(leaseKey);\n  if (postNavigationSession && tab.windowId !== postNavigationSession.windowId) {\n    console.warn(`[opencli] Tab ${tabId} drifted to window ${tab.windowId} during navigation, moving back to ${postNavigationSession.windowId}`);\n    try {\n      await chrome.tabs.move(tabId, { windowId: postNavigationSession.windowId, index: -1 });\n      tab = await chrome.tabs.get(tabId);\n    } catch (moveErr) {\n      console.warn(`[opencli] Failed to recover drifted tab: ${moveErr}`);\n    }\n  }\n\n  return pageScopedResult(cmd.id, tabId, { title: tab.title, url: tab.url, timedOut });\n}\n\nasync function handleTabs(cmd: Command, leaseKey: string): Promise<Result> {\n  const session = automationSessions.get(leaseKey);\n  if (session && !session.owned && cmd.op !== 'list') {\n    return {\n      id: cmd.id,\n      ok: false,\n      errorCode: 'bound_tab_mutation_blocked',","sourceCodeStart":1793,"sourceCodeEnd":1829,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/extension/src/background.ts#L1793-L1829","documentation":"This warning is logged by the Chrome-extension automation layer after a navigation completes: the tab was expected to stay in the window bound to its automation session, but chrome reported it now lives in a different window (often because a tab-manager extension regrouped tabs). The code logs this warning and then attempts chrome.tabs.move to return the tab to the session's window, preserving per-session window isolation for concurrent automations. It is a warning plus self-healing action, not a thrown error.","triggerScenarios":"An automation session (automationSessions keyed by leaseKey) navigated a tab via chrome.tabs.update/create, and after navigation tab.windowId differs from postNavigationSession.windowId — typically another extension or the user moved/regrouped the tab into a different window between navigation start and completion.","commonSituations":"Running opencli browser automation alongside tab-management extensions (Tab Groups, OneTab, Session Buddy); the user dragging the automated tab to another window mid-run; scripts that reorganize windows while the daemon drives a headful profile.","solutions":["Disable or pause third-party tab-management extensions in the profile used for automation so tabs are not regrouped mid-navigation.","Rerun the command; the code moves the tab back automatically, so the warning is usually self-correcting.","If drift recurs, check the [opencli] 'Failed to recover drifted tab' companion message for the underlying chrome.tabs.move failure.","Avoid manually moving tabs while an opencli automation session is active on that profile."],"exampleFix":"// before: user/extension moves tab during navigation -> warning\n// after: prevent interference by disabling tab-grouping extensions in the automation profile,\n// or keep the session window focused during the run","handlingStrategy":"retry","validationCode":"const status = await chrome.tabs.get(tabId);\nif (status.windowId !== expectedWindowId) {\n  await chrome.windows.get(expectedWindowId); // ensure target window exists\n}","typeGuard":"function isInWindow(tab, windowId) {\n  return typeof tab?.windowId === 'number' && tab.windowId === windowId;\n}","tryCatchPattern":"try {\n  await runAutomation(tabId);\n} catch (e) {\n  const tab = await chrome.tabs.get(tabId).catch(() => null);\n  if (!tab || tab.windowId !== expectedWindowId) {\n    // treat as transient drift: re-create the tab in the session window and retry once\n  }\n}","preventionTips":["Disable tab-grouping/tab-management extensions in profiles used for automation.","Do not manually drag automated tabs between windows while a session is active.","Treat the drift warning as self-healing; only intervene if it repeats with a recovery failure."],"tags":["chrome-extension","tabs","session-isolation","race-condition"],"backgroundTag":"tab-window-drift","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}