---
title: validateUIMessages
description: API Reference for validateUIMessages
---

# `validateUIMessages`

`validateUIMessages` is an async function that validates UI messages against schemas for metadata, data parts, and tools. It ensures type safety and data integrity for your message arrays before processing or rendering.

Structural validation stops at the first invalid element in message and part arrays.
Part types and tool states select the applicable schema before its fields are validated.
The error retains the failing element's path without accumulating errors for every
malformed element. Valid message and part arrays have no SDK-imposed count limit;
apply request size and message history limits appropriate for your application.

## Basic Usage

Simple validation without custom schemas:

```typescript
import { validateUIMessages } from 'ai';

const messages = [
  {
    id: '1',
    role: 'user',
    parts: [{ type: 'text', text: 'Hello!' }],
  },
];

const validatedMessages = await validateUIMessages({
  messages,
});
```

## Advanced Usage

Comprehensive validation with custom metadata, data parts, and tools:

```typescript
import { validateUIMessages, tool } from 'ai';
import { z } from 'zod';

// Define schemas
const metadataSchema = z.object({
  timestamp: z.string().datetime(),
  userId: z.string(),
});

const dataSchemas = {
  chart: z.object({
    data: z.array(z.number()),
    labels: z.array(z.string()),
  }),
  image: z.object({
    url: z.string().url(),
    caption: z.string(),
  }),
};

const tools = {
  weather: tool({
    description: 'Get weather info',
    inputSchema: z.object({
      location: z.string(),
    }),
    execute: async ({ location }) => `Weather in ${location}: sunny`,
  }),
};

// Messages with custom parts
const messages = [
  {
    id: '1',
    role: 'user',
    metadata: { timestamp: '2024-01-01T00:00:00Z', userId: 'user123' },
    parts: [
      { type: 'text', text: 'Show me a chart' },
      {
        type: 'data-chart',
        data: { data: [1, 2, 3], labels: ['A', 'B', 'C'] },
      },
    ],
  },
  {
    id: '2',
    role: 'assistant',
    parts: [
      {
        type: 'tool-weather',
        toolCallId: 'call_123',
        state: 'output-available',
        input: { location: 'San Francisco' },
        output: 'Weather in San Francisco: sunny',
      },
    ],
  },
];

// Validate with all schemas
const validatedMessages = await validateUIMessages({
  messages,
  metadataSchema,
  dataSchemas,
  tools,
});
```

When validating approval messages produced with
`experimental_refineToolInput`, pass the same refinement functions so
`validateUIMessages` can reconstruct and verify the approved input:

```typescript
const experimental_refineToolInput = {
  weather: (input: { location: string }) => ({
    location: input.location.trim(),
  }),
};

const validatedMessages = await validateUIMessages({
  messages,
  tools,
  experimental_refineToolInput,
});
```

## Deprecated `rawInput` field

For backward compatibility, validation still accepts `rawInput` on tool parts
in the `output-error` state. When a defined `rawInput` value is found,
`validateUIMessages` emits an AI SDK deprecation warning through
`AI_SDK_LOG_WARNINGS`.

Migrate persisted messages to store tool arguments in `input` and remove
`rawInput`. For backward compatibility, conversion uses `rawInput` as a
fallback when `input` is `null` or `undefined`. `rawInput` will be removed in
the next major version.
