jackwener/OpenCLI · warning

[opencli] Tab ${tabId} drifted to window ${tab.windowId} dur

Error message

[opencli] Tab ${tabId} drifted to window ${tab.windowId} during navigation, moving back to ${postNavigationSession.windowId}

What it means

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.

Source

Thrown at extension/src/background.ts:1811

      } catch { /* tab gone */ }
    }, 100);

    // Timeout fallback with warning
    timeoutTimer = setTimeout(() => {
      timedOut = true;
      console.warn(`[opencli] Navigate to ${targetUrl} timed out after 15s`);
      finish();
    }, 15000);
  });

  let tab = await chrome.tabs.get(tabId);

  // Post-navigation drift detection: if the tab moved to another window
  // during navigation (e.g. a tab-management extension regrouped it),
  // try to move it back to maintain session isolation.
  const postNavigationSession = automationSessions.get(leaseKey);
  if (postNavigationSession && tab.windowId !== postNavigationSession.windowId) {
    console.warn(`[opencli] Tab ${tabId} drifted to window ${tab.windowId} during navigation, moving back to ${postNavigationSession.windowId}`);
    try {
      await chrome.tabs.move(tabId, { windowId: postNavigationSession.windowId, index: -1 });
      tab = await chrome.tabs.get(tabId);
    } catch (moveErr) {
      console.warn(`[opencli] Failed to recover drifted tab: ${moveErr}`);
    }
  }

  return pageScopedResult(cmd.id, tabId, { title: tab.title, url: tab.url, timedOut });
}

async function handleTabs(cmd: Command, leaseKey: string): Promise<Result> {
  const session = automationSessions.get(leaseKey);
  if (session && !session.owned && cmd.op !== 'list') {
    return {
      id: cmd.id,
      ok: false,
      errorCode: 'bound_tab_mutation_blocked',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Disable or pause third-party tab-management extensions in the profile used for automation so tabs are not regrouped mid-navigation.
  2. Rerun the command; the code moves the tab back automatically, so the warning is usually self-correcting.
  3. If drift recurs, check the [opencli] 'Failed to recover drifted tab' companion message for the underlying chrome.tabs.move failure.
  4. Avoid manually moving tabs while an opencli automation session is active on that profile.

Example fix

// before: user/extension moves tab during navigation -> warning
// after: prevent interference by disabling tab-grouping extensions in the automation profile,
// or keep the session window focused during the run
Defensive patterns

Strategy: retry

Validate before calling

const status = await chrome.tabs.get(tabId);
if (status.windowId !== expectedWindowId) {
  await chrome.windows.get(expectedWindowId); // ensure target window exists
}

Type guard

function isInWindow(tab, windowId) {
  return typeof tab?.windowId === 'number' && tab.windowId === windowId;
}

Try / catch

try {
  await runAutomation(tabId);
} catch (e) {
  const tab = await chrome.tabs.get(tabId).catch(() => null);
  if (!tab || tab.windowId !== expectedWindowId) {
    // treat as transient drift: re-create the tab in the session window and retry once
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/15c07d75f9065c7d. Report an issue: GitHub.