vercel/ai · error

Invalid state

Error message

Invalid state

What it means

After confirming the provider exists, `useUIState` validates that the context value is the expected `[state, setState]` tuple. If it is not an array, the provider installed a malformed value, indicating the `InternalUIStateProvider` was provided something other than what `createAI`/`<AI>` supplies.

Source

Thrown at packages/rsc/src/shared-client/context.tsx:134

            {children}
          </InternalSyncUIStateProvider.Provider>
        </InternalActionProvider.Provider>
      </InternalUIStateProvider.Provider>
    </InternalAIStateProvider.Provider>
  );
}

export function useUIState<AI extends AIProvider = any>() {
  type T = InferUIState<AI, any>;

  const state = React.useContext<
    [T, (v: T | ((v_: T) => T)) => void] | null | undefined
  >(InternalUIStateProvider);
  if (state === null) {
    throw new Error('`useUIState` must be used inside an <AI> provider.');
  }
  if (!Array.isArray(state)) {
    throw new Error('Invalid state');
  }
  if (state[0] === undefined) {
    throw new Error(
      '`initialUIState` must be provided to `createAI` or `<AI>`',
    );
  }
  return state;
}

// TODO: How do we avoid causing a re-render when the AI state changes but you
// are only listening to a specific key? We need useSES perhaps?
function useAIState<AI extends AIProvider = any>(): [
  InferAIState<AI, any>,
  (newState: ValueOrUpdater<InferAIState<AI, any>>) => void,
];
function useAIState<AI extends AIProvider = any>(
  key: keyof InferAIState<AI, any>,
): [

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Remove any test mock overriding `InternalUIStateProvider` and use the real `AI` provider
  2. Ensure only one version of the `ai` package is installed (`pnpm why ai` / `npm ls ai`) and dedupe
  3. Reinstall node_modules to fix module duplication after upgrades
  4. Render the provider via the component returned by `createAI` instead of constructing context values manually

Example fix

// before (test mock)
<InternalUIStateProvider value={{ uiState }}>
  <MyComponent />
</InternalUIStateProvider>
// after
const AI = createAI({ ... });
render(<AI initialUIState={initialUiState}><MyComponent /></AI>);
Defensive patterns

Strategy: type-guard

Validate before calling

const ctx = React.useContext(InternalUIStateProvider);
if (!Array.isArray(ctx)) {
  throw new Error('InternalUIStateProvider value must be a [state, setState] tuple');
}

Type guard

function isUIStateTuple(v: unknown): v is [unknown, (fn: unknown) => void] {
  return Array.isArray(v) && v.length === 2 && typeof v[1] === 'function';
}

Try / catch

try {
  const [uiState] = useUIState();
} catch (err) {
  if (String(err).includes('Invalid state')) {
    console.error('Provider context malformed — check for duplicate ai packages or bad test mocks');
  }
  throw err;
}

Prevention

When it happens

Trigger: A custom/mocked `InternalUIStateProvider` value that is not a tuple; intercepting or monkey-patching the context in tests; version skew where a mismatched `ai` package builds the context differently than the one consuming it.

Common situations: Test mocks that supply `{ uiState }` objects instead of the `[value, setter]` tuple; duplicate `ai` package copies (different module instances) causing context mismatch after dependency upgrades; manually rendering `InternalAIProvider` with wrong props.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/bc5f63fa267a449e. Report an issue: GitHub.