{"slug": "ai-sdk-7-0-160-started-enforcing-datapartschemas-your-loading-states-might-now", "title": "AI SDK 7.0.160 Started Enforcing dataPartSchemas. Your Loading States Might Now Throw", "summary": "A developer's testing of the Vercel AI SDK found that ai 7.0.160 turned on validation for `dataPartSchemas` passed to `useChat` and `Chat` that had previously never run, so streams that worked on 7.0.159 can now fail with a `TypeValidationError`. The fix for issue #24241 (PR #24298) looks up schemas by the bare part name, meaning every chunk — including transient parts and progressive loading updates — is now checked, and a schema written only for the final shape rejects the loading chunk. The developer recommends schemas that describe every state the server sends, such as a discriminated union on `status`, which kept the same stream in `status: ready` across versions.", "body_md": "If you pass `dataPartSchemas` to `useChat` and bump `ai` to 7.0.160 or later, a chat that worked yesterday can end up in `status: 'error'` with a `TypeValidationError`. You didn't change anything. Your schemas just started running.\n\n`useChat` and `Chat` accept `dataPartSchemas`, keyed by the bare part name (` weather` for a `data-weather` part). The stream processor looked the schema up by the full chunk type (`data-weather`), so the lookup always missed and streamed data parts were never validated. That's [issue #24241](https://github.com/vercel/ai/issues/24241), fixed in [PR #24298](https://github.com/vercel/ai/pull/24298) and shipped in [ai 7.0.160](https://github.com/vercel/ai/releases/tag/ai%407.0.160): \"Invalid data parts now raise a `TypeValidationError`.\"\n\nSo a patch release turned on a check that was configured but never ran.\n\nI didn't want to guess at the edge cases, so I drove the `Chat` class from `@ai-sdk/react` with a fake transport that replays fixed UI message chunks. No model, no network. `useChat` runs on that same class (its [`chat` option](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) even takes an existing `Chat` instance), so the stream handling is the same code path. I ran the same script against ai 7.0.159 with `@ai-sdk/react` 4.0.163, ai 7.0.162 with `@ai-sdk/react` 4.0.166, and ai 6.0.322 with `@ai-sdk/react` 3.0.325, all with zod 4.6.7 on Node 20.19.2.\n\n| Stream | 7.0.159 | 7.0.162 | \n|---|---|---|\n| Valid `data-weather` part | ready | ready | \n| `city: 42` , then some text | ready, bad data kept in `parts` , text arrives | error, no assistant message at all | \n| Loading update without `weather` , then the final value | ready | error, earlier text kept, final value lost | \n| Transient part that fails the schema | ready, `onData` called | error, `onData` not called | \n| `data-notice` part with no schema | ready | ready | \n\nOn 6.0.322 every row matched the 7.0.159 column: bad data went through without an error.\n\nThe [streaming data docs](https://ai-sdk.dev/docs/ai-sdk-ui/streaming-data) use a progressive pattern: write `{ city, status: 'loading' }` first, then write to the same `id` again with the real value. The docs type `weather` as optional (`weather?: string`), which fits that pattern. But if your zod schema was written for the finished shape, the loading chunk fails now. Here's the excerpt from my test script (`start` and `end` are the start/finish chunks, `text()` writes one text part, and `run()` sends a message through `Chat` with these chunks):\n\n``` js\nconst strictSchemas = {\n  weather: z.object({\n    city: z.string(),\n    weather: z.string(),\n    status: z.enum(['loading', 'success']),\n  }),\n};\n\n// Case 3: a loading update, then the final value under the same id\nawait run('3 loading update without weather, then final', [...start,\n  ...text('t0', 'Checking...'),\n  { type: 'data-weather', id: 'w1', data: { city: 'Berlin', status: 'loading' } },\n  { type: 'data-weather', id: 'w1', data: { city: 'Berlin', weather: 'sunny', status: 'success' } }, ...end]);\n```\n\nOn 7.0.162 this ended with `Type validation failed for message.parts[2].data (data-weather, id: \"w1\")`. The \"Checking...\" text that streamed before it stayed in the message, the final value never arrived, and `chat.status` was `error`.\n\nEvery chunk is checked, not just the last one per `id`. Transient parts too, even though they never land in `message.parts`.\n\nMake the schema describe every state the server actually sends. A discriminated union keeps the final shape strict:\n\n``` js\nconst unionSchemas = {\n  weather: z.discriminatedUnion('status', [\n    z.object({ status: z.literal('loading'), city: z.string() }),\n    z.object({ status: z.literal('success'), city: z.string(), weather: z.string() }),\n  ]),\n};\n```\n\nWith this schema the same stream finished with `status: ready` on both versions, and the part ended up as `{ city: 'Berlin', weather: 'sunny', status: 'success' }`.\n\nBefore you upgrade, I'd do three things:\n\n`dataPartSchemas`.` data-*` type in there, check every `writer.write()` on the server against its schema, including loading, progress and transient writes.`error` from `useChat`. In my runs a failed part stopped the whole response, so a silent failure here looks like a chat that just stops.\nData parts with no schema aren't checked at all, so a schema-less type won't start failing.\n\nI'd rather have the error than let `city: 42` slip into `message.parts` without a word, which is what 7.0.159 did. Have you hit this one after updating, or were your schemas already matching what the server sends?", "url": "https://wpnews.pro/news/ai-sdk-7-0-160-started-enforcing-datapartschemas-your-loading-states-might-now", "canonical_source": "https://dev.to/sushilmagare10/ai-sdk-70160-started-enforcing-datapartschemas-your-loading-states-might-now-throw-31a5", "published_at": "2026-11-03 02:41:31+00:00", "updated_at": "2026-11-03 02:52:35.213369+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-products"], "entities": ["Vercel", "AI SDK", "useChat", "Chat", "@ai-sdk/react", "zod"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/ai-sdk-7-0-160-started-enforcing-datapartschemas-your-loading-states-might-now", "markdown": "https://wpnews.pro/news/ai-sdk-7-0-160-started-enforcing-datapartschemas-your-loading-states-might-now.md", "text": "https://wpnews.pro/news/ai-sdk-7-0-160-started-enforcing-datapartschemas-your-loading-states-might-now.txt", "jsonld": "https://wpnews.pro/news/ai-sdk-7-0-160-started-enforcing-datapartschemas-your-loading-states-might-now.jsonld"}}