facebook/docusaurus · error · ReactContextError

Hook is called outside the <CodeBlockContextProvider>.

Error message

Hook is called outside the <CodeBlockContextProvider>. 

What it means

Thrown by `useCodeBlockContext()` when its context is `null`, meaning the hook was called outside `<CodeBlockContextProvider>`. The provider wraps each rendered `<CodeBlock>` (and CodeBlock MDX) and exposes metadata + word-wrap state; consumers must be descendants.

Source

Thrown at packages/docusaurus-theme-common/src/utils/codeBlockUtils.tsx:495

  wordWrap: WordWrap;
  children: ReactNode;
}): ReactNode {
  // Should we optimize this in 2 contexts?
  // Unlike metadata, wordWrap is stateful and likely to trigger re-renders
  const value: CodeBlockContextValue = useMemo(() => {
    return {metadata, wordWrap};
  }, [metadata, wordWrap]);
  return (
    <CodeBlockContext.Provider value={value}>
      {children}
    </CodeBlockContext.Provider>
  );
}

export function useCodeBlockContext(): CodeBlockContextValue {
  const value = useContext(CodeBlockContext);
  if (value === null) {
    throw new ReactContextError('CodeBlockContextProvider');
  }
  return value;
}

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Keep sub-components that call `useCodeBlockContext()` inside `<CodeBlockContextProvider>`.
  2. Wrap isolated test renders of those sub-components with the provider and a mock value.
  3. Diff swizzled CodeBlock against upstream to confirm the provider still wraps the inner tree.

Example fix

// before — subcomponent rendered outside provider
<CopyButton /> // throws
// after
<CodeBlockContextProvider value={mockValue}>
  <CopyButton />
</CodeBlockContextProvider>
Defensive patterns

Strategy: validation

Validate before calling

import {useContext} from 'react';
import {CodeBlockContext} from '@docusaurus/theme-common/internal';
function useCodeBlockContextSafe() {
  return useContext(CodeBlockContext); // null if outside provider
}

Try / catch

try {
  const {metadata, wordWrap} = useCodeBlockContext();
} catch (e) {
  if (e instanceof Error && e.message.includes('CodeBlockContextProvider')) return null;
  throw e;
}

Prevention

When it happens

Trigger: A component that reads code-block metadata (e.g. a swizzled `CodeBlock` sub-part like the copy button or word-wrap toggle) is rendered outside the provider subtree. Common in isolated tests or swizzled layouts that restructure the CodeBlock tree.

Common situations: Swizzling `CodeBlock` and splitting sub-components so the provider no longer wraps them; rendering a CodeBlock child in isolation (Storybook/test) without the provider; portal escaping the provider.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/98e08f3ccf6094bb. Report an issue: GitHub.