different-ai/openwork · error · Error
Tab order must include every open tab.
Error message
Tab order must include every open tab.
What it means
reorderBrowserTabs validates that the proposed order array has exactly the same length as the current browserTabOrder; anything shorter or longer throws this error, since a reorder must be a full permutation of open tabs, not a partial or extended list.
Source
Thrown at apps/desktop/electron/browser-panel.mjs:682
const tabsToClose = closedTabIds
.map((tabId) => browserTabs.get(tabId))
.filter(Boolean);
hideBrowserView();
browserTabs.clear();
browserTabOrder = [];
activeBrowserTabId = null;
for (const tab of tabsToClose) {
try { tab.view.webContents.close(); } catch { /* already destroyed */ }
}
sendToRenderer("openwork:browser:panel-closed");
sendBrowserState();
return closedTabIds;
}
function reorderBrowserTabs(tabIds) {
const nextOrder = Array.isArray(tabIds) ? tabIds.map(String) : [];
if (nextOrder.length !== browserTabOrder.length) {
throw new Error("Tab order must include every open tab.");
}
if (new Set(nextOrder).size !== nextOrder.length) {
throw new Error("Tab order must not contain duplicate tabs.");
}
const current = new Set(browserTabOrder);
if (nextOrder.some((tabId) => !current.has(tabId))) {
throw new Error("Tab order contains an unknown tab.");
}
browserTabOrder = nextOrder;
sendBrowserState();
return listBrowserTabs();
}
function sendBrowserState() {
sendToRenderer("openwork:browser:state", browserStatePayload());
}
/**View on GitHub (pinned to 2b7df46e8a)
Solutions
- Fetch the current tab order and send all open tab IDs in the desired new sequence
- Build the reorder payload from a fresh listBrowserTabs() result rather than cached state
- Reconcile the client snapshot with the server state when tab counts disagree, then retry
Example fix
// before reorderBrowserTabs([draggedTabId]); // after const order = listBrowserTabs().map(t => t.tabId); reorderBrowserTabs([draggedTabId, ...order.filter(id => id !== draggedTabId)]);
Defensive patterns
Strategy: validation
Validate before calling
function canReorder(tabIds, currentOrder) {
const next = Array.isArray(tabIds) ? tabIds.map(String) : [];
return next.length === currentOrder.length;
}
if (!canReorder(ids, listBrowserTabs().map(t => t.tabId))) throw new Error('order must contain every open tab'); Type guard
function isFullPermutation(ids, current) {
const a = ids.map(String), b = current.map(String);
return a.length === b.length && new Set(a).size === a.length && a.every(id => new Set(b).has(id));
} Try / catch
try {
reorderBrowserTabs(order);
} catch (e) {
if (e.message === 'Tab order must include every open tab.') {
const fresh = listBrowserTabs().map(t => t.tabId);
reorderBrowserTabs(order.filter(id => fresh.includes(id)).concat(fresh.filter(id => !order.includes(id))));
} else throw e;
} Prevention
- Always build reorder payloads from a fresh listBrowserTabs() snapshot
- Never send partial orders (e.g. just the dragged tab)
- Re-sync client tab state on open/close events before reordering
- Validate length === open-tab count client-side first
When it happens
Trigger: Calling reorder with a subset of tab IDs (e.g. only the dragged tab), an empty array when tabs are open, or an array that includes extra IDs beyond the open count (possibly from a stale UI snapshot taken before/after another tab opened).
Common situations: UI sending only the moved tab's id; concurrent tab open/close racing the reorder request; client built the order from an outdated browser-state snapshot.
Related errors
- Tab order must not contain duplicate tabs.
- Tab order contains an unknown tab.
- Agent context diagnostics timeout must be between 1 ms and 3
- Invalid cloud provider sync response.
- Invalid cloud provider sync status.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/f9d008aa90579128.
Report an issue: GitHub.