{"record":{"id":"f1b39e1f2f96b617","repo":"GitbookIO/gitbook","slug":"useai-must-be-used-within-aicontextprovider","errorCode":null,"errorMessage":"useAI must be used within AIContextProvider","messagePattern":"useAI must be used within AIContextProvider","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/gitbook/src/components/AI/useAI.tsx","lineNumber":71,"sourceCode":"     */\n    icon: ReactNode;\n};\n\nconst AIContext = React.createContext<AIConfig | null>(null);\n\nexport function AIContextProvider(props: React.PropsWithChildren<AIConfig>): React.ReactElement {\n    const { aiMode, trademark, suggestions, greeting, assistantName, children } = props;\n    const value = React.useMemo(\n        () => ({ aiMode, trademark, suggestions, greeting, assistantName }),\n        [aiMode, trademark, suggestions, greeting, assistantName]\n    );\n    return <AIContext.Provider value={value}>{children}</AIContext.Provider>;\n}\n\nexport function useAIConfig(): AIConfig {\n    const ctx = React.useContext(AIContext);\n    if (!ctx) {\n        throw new Error('useAI must be used within AIContextProvider');\n    }\n    return ctx;\n}\n\ntype AIContext = {\n    config: AIConfig;\n    assistants: Assistant[];\n};\n\n/**\n * Unified assistants list combining the built-in GitBook Assistant (when enabled)\n * with any custom assistants registered at runtime.\n */\nexport function useAI(): AIContext {\n    const config = useAIConfig();\n    const chat = useAIChatState();\n    const chatController = useAIChatController();\n    const language = useLanguage();","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/GitbookIO/gitbook/blob/db67585ee243d063c459a855988f21612cea9c95/packages/gitbook/src/components/AI/useAI.tsx#L53-L89","documentation":"Thrown by useAIConfig(), a React hook in the GitBook AI components that reads configuration from an AIContext React context. Like all 'must be used within Provider' errors, it means the hook's useContext call returned null because no AIContextProvider ancestor rendered the provider, so there is no config to return.","triggerScenarios":"Calling useAIConfig() in a component rendered outside <AIContextProvider>...</AIContextProvider>; rendering the provider and consumer in different React roots; memoization or portal techniques that move the consumer outside the provider's subtree; forgetting to wrap a custom page/section that uses AI components.","commonSituations":"Adding AI components to a custom layout or standalone test render without the provider; unit tests (React Testing Storybook / RTL) rendering the consumer directly; refactors that lifted the provider out of a subtree that still consumes it.","solutions":["Wrap the consuming component (or its page) in <AIContextProvider> (the component exporting the provider shown above the hook) with the required config value.","If it happens in tests, render the consumer inside the provider in your test wrapper.","Ensure the provider is actually an ancestor in the same React tree (not a sibling or a separate root).","For compound AI components, use the top-level exported component that internally sets up the provider rather than consuming hooks directly."],"exampleFix":"// before\nexport function MyAssistant() {\n    const config = useAIConfig(); // throws\n    ...\n}\n\n// after\nexport function MyAssistant() {\n    return (\n        <AIContextProvider config={config}>\n            <MyAssistantInner />\n        </AIContextProvider>\n    );\n}\nfunction MyAssistantInner() {\n    const config = useAIConfig(); // ok\n    ...\n}","handlingStrategy":"type-guard","validationCode":"// Ensure the provider is an ancestor before rendering consumers:\n<MyAIApp>\n    <AIContextProvider config={config}>\n        <ConsumesUseAIConfig />\n    </AIContextProvider>\n</MyAIApp>","typeGuard":"function hasAIConfig(ctx: AIConfig | null): ctx is AIConfig {\n    return ctx !== null;\n}\n\nfunction useOptionalAIConfig(): AIConfig | null {\n    return React.useContext(AIContext); // null-safe alternative to useAIConfig\n}","tryCatchPattern":"try {\n    const config = useAIConfig();\n} catch {\n    // note: hooks that throw still ran; prefer structural fixes over catching\n}","preventionTips":["Never call context-consuming hooks outside the documented provider tree.","Create a nullable variant hook (useContext directly) when a component might render provider-less.","Wrap test renders with the provider fixture."],"tags":["react","hooks","context","provider","ai","gitbook"],"backgroundTag":"react-context-provider-missing","analyzedSha":"db67585ee243d063c459a855988f21612cea9c95","analyzedAt":"2026-08-28T17:49:47.831Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}