facebook/docusaurus · error · Error
Can't select invalid tab value=${newValue}
Error message
Can't select invalid tab value=${newValue} What it means
The selectValue function returned from the Tabs hook (and exposed via useTabs context) only accepts a value that exists in tabValues. It calls isValidValue and throws 'Can't select invalid tab value=...' to forbid programmatically activating a tab that does not exist. This guards internal invariants when consumers drive tab selection from external state.
Source
Thrown at packages/docusaurus-theme-common/src/utils/tabsUtils.tsx:274
const valueToSync = (() => {
const value = queryStringValue ?? storageValue;
if (!isValidValue({value, tabValues})) {
return null;
}
return value;
})();
// Sync in a layout/sync effect is important, for useScrollPositionBlocker
// See https://github.com/facebook/docusaurus/issues/8625
useIsomorphicLayoutEffect(() => {
if (valueToSync) {
setSelectedValue(valueToSync);
}
}, [valueToSync]);
const selectValue = useCallback(
(newValue: string) => {
if (!isValidValue({value: newValue, tabValues})) {
throw new Error(`Can't select invalid tab value=${newValue}`);
}
setSelectedValue(newValue);
setQueryString(newValue);
setStorageValue(newValue);
},
[setQueryString, setStorageValue, tabValues],
);
return {
selectedValue,
selectValue,
tabValues,
lazy: props.lazy ?? false,
block: props.block ?? false,
};
}
const TabsContext = createContext<TabsContextValue | null>(null);View on GitHub (pinned to 3f483e80e3)
Solutions
- Guard the call: only invoke selectValue when tabValues.some(t => t.value === next).
- Refresh tabValues before selecting (ensure the target value is rendered first).
- If the value comes from URL/storage, rely on the built-in sync which already filters invalid values via isValidValue in valueToSync.
Example fix
// before
const {selectValue} = useTabs();
selectValue(maybeValue);
// after
const {selectValue, tabValues} = useTabs();
if (tabValues.some((t) => t.value === maybeValue)) {
selectValue(maybeValue);
} Defensive patterns
Strategy: type-guard
Validate before calling
const {selectValue, tabValues} = useTabs();
if (tabValues.some((t) => t.value === next)) {
selectValue(next);
} Type guard
const isSelectableTabValue = (
v: string,
tabValues: readonly {value: string}[],
): v is string => tabValues.some((t) => t.value === v); Prevention
- Never call selectValue with a value that was not in tabValues at render time.
- When tabValues are async/dynamic, await their population before driving selection.
- Centralize external->tab syncing through one validated helper.
When it happens
Trigger: Call tabs.selectValue('linux') when no <TabItem value="linux"> exists; feed selectValue from a stale closure after tabValues changed asynchronously; sync from URL/localStorage with an out-of-date value list.
Common situations: External state machines driving Tabs; dynamically rendered tab lists where a value is removed while a selectValue call is in flight; tests calling selectValue with a literal not present in fixtures.
Related errors
- useTabsContext() must be used within a Tabs component
- Hook is called outside the <AnnouncementBarProvider>.
- Hook is called outside the <ColorModeProvider>. Please see h
- Hook is called outside the <NavbarMobileSidebarProvider>.
- Hook is called outside the <NavbarSecondaryMenuContentProvid
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/7a38e38dd120a73f.
Report an issue: GitHub.