{"record":{"id":"ff634d4d3a4e9fb9","repo":"vercel/ai","slug":"usesyncuistate-must-be-used-inside-an-ai-provi","errorCode":null,"errorMessage":"`useSyncUIState` must be used inside an <AI> provider.","messagePattern":"`useSyncUIState` must be used inside an <AI> provider\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/rsc/src/shared-client/context.tsx","lineNumber":217,"sourceCode":"  } else {\n    return [state[0][args[0]], setter];\n  }\n}\n\nexport function useActions<AI extends AIProvider = any>() {\n  type T = InferActions<AI, any>;\n\n  const actions = React.useContext<T>(InternalActionProvider);\n  return actions;\n}\n\nexport function useSyncUIState() {\n  const syncUIState = React.useContext<() => Promise<void>>(\n    InternalSyncUIStateProvider,\n  );\n\n  if (syncUIState === null) {\n    throw new Error('`useSyncUIState` must be used inside an <AI> provider.');\n  }\n\n  return syncUIState;\n}\n\nexport { useAIState };\n","sourceCodeStart":199,"sourceCodeEnd":224,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/rsc/src/shared-client/context.tsx#L199-L224","documentation":"useSyncUIState is a React hook in the RSC package that requires a surrounding <AI> provider from `ai/rsc`. It reads a sync callback from an internal React context, which is only populated when the component tree is rendered inside <AI>. When the context value is null (no provider), the hook throws to prevent calling a sync function that does not exist.","triggerScenarios":"Calling useSyncUIState() in a component that is not a descendant of <AI>, e.g. rendering the component outside the provider, forgetting to wrap the app, or using the hook in a different React root (portal/second root) that has no provider.","commonSituations":"Adding a component that uses the hook to a page where the <AI> wrapper was removed during refactoring; rendering part of the UI in a separate root; copying hook usage from docs without adding the provider in a new route.","solutions":["Wrap the component using the hook in the <AI> provider from `ai/rsc`","Check that the component is rendered as a child of <AI>, not a sibling or in a different React root","If the component renders into a portal, ensure the portal is created inside the <AI> subtree"],"exampleFix":"// before\nexport default function Page() {\n  return <MyComponent />; // uses useSyncUIState\n}\n// after\nimport { AI } from 'ai/rsc';\nexport default function Page() {\n  return (\n    <AI>\n      <MyComponent />\n    </AI>\n  );\n}","handlingStrategy":"validation","validationCode":"function useSafeSyncUIState() {\n  const inProvider = React.useContext(InternalSyncUIStateProvider) !== null;\n  if (!inProvider) throw new Error('useSyncUIState requires <AI> provider');\n  return useSyncUIState();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always render hook consumers inside <AI> from ai/rsc","Keep portals and secondary roots inside the provider subtree","Add a component test that renders the consumer outside <AI> and asserts the error"],"tags":["react","context","hooks","rsc"],"backgroundTag":"missing-react-provider","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}