Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:23:53 +08:00
commit caa3746d36
21 changed files with 4452 additions and 0 deletions

303
references/top-ui-errors.md Normal file
View File

@@ -0,0 +1,303 @@
# AI SDK UI - Top 12 Errors & Solutions
Common AI SDK UI errors with actionable solutions.
**Last Updated**: 2025-10-22
---
## 1. useChat Failed to Parse Stream
**Error**: `SyntaxError: Unexpected token in JSON at position X`
**Cause**: API route not returning proper stream format.
**Solution**:
```typescript
// ✅ CORRECT (App Router)
export async function POST(req: Request) {
const result = streamText({ /* ... */ });
return result.toDataStreamResponse(); // Correct method
}
// ✅ CORRECT (Pages Router)
export default async function handler(req, res) {
const result = streamText({ /* ... */ });
return result.pipeDataStreamToResponse(res); // Correct method
}
// ❌ WRONG
return new Response(result.textStream); // Missing stream protocol
```
---
## 2. useChat No Response
**Cause**: API route not streaming correctly or wrong method.
**Solution**:
```typescript
// Check 1: Are you using the right method?
// App Router: toDataStreamResponse()
// Pages Router: pipeDataStreamToResponse()
// Check 2: Is your API route returning a Response?
export async function POST(req: Request) {
const result = streamText({ model: openai('gpt-4'), messages });
return result.toDataStreamResponse(); // Must return this!
}
// Check 3: Check network tab - is the request completing?
// If status is 200 but no data: likely streaming issue
```
---
## 3. Unclosed Streams
**Cause**: Stream not properly closed in API.
**Solution**:
```typescript
// ✅ GOOD: SDK handles closing automatically
export async function POST(req: Request) {
const result = streamText({ model: openai('gpt-4'), messages });
return result.toDataStreamResponse();
}
// ❌ BAD: Manual stream handling (error-prone)
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
// ...must manually close!
controller.close();
}
});
```
**GitHub Issue**: #4123
---
## 4. Streaming Not Working When Deployed
**Cause**: Deployment platform buffering responses.
**Solution**:
- **Vercel**: Auto-detects streaming (no config needed)
- **Netlify**: Ensure Edge Functions enabled
- **Cloudflare Workers**: Use `toDataStreamResponse()`
- **Other platforms**: Check for response buffering settings
```typescript
// Vercel - works out of the box
export async function POST(req: Request) {
const result = streamText({ /* ... */ });
return result.toDataStreamResponse();
}
```
**Docs**: https://vercel.com/docs/functions/streaming
---
## 5. Streaming Not Working When Proxied
**Cause**: Proxy (nginx, Cloudflare, etc.) buffering responses.
**Solution**:
**Nginx**:
```nginx
location /api/ {
proxy_pass http://localhost:3000;
proxy_buffering off; # Disable buffering
proxy_cache off;
}
```
**Cloudflare**: Disable "Auto Minify" in dashboard
---
## 6. Strange Stream Output (0:... characters)
**Error**: Seeing raw stream protocol like `0:"Hello"` in browser.
**Cause**: Not using correct hook or consuming stream directly.
**Solution**:
```tsx
// ✅ CORRECT: Use useChat hook
const { messages } = useChat({ api: '/api/chat' });
// ❌ WRONG: Consuming stream directly
const response = await fetch('/api/chat');
const reader = response.body.getReader(); // Don't do this!
```
---
## 7. Stale Body Values with useChat
**Cause**: `body` captured at first render only.
**Solution**:
```tsx
// ❌ BAD: body captured once
const { userId } = useUser();
const { messages } = useChat({
body: { userId }, // Stale! Won't update if userId changes
});
// ✅ GOOD: Use data in sendMessage
const { userId } = useUser();
const { messages, sendMessage } = useChat();
sendMessage({
content: input,
data: { userId }, // Fresh value on each send
});
```
---
## 8. Custom Headers Not Working with useChat
**Cause**: Headers not passed correctly.
**Solution**:
```tsx
// ✅ CORRECT
const { messages } = useChat({
headers: {
'Authorization': `Bearer ${token}`,
'X-Custom-Header': 'value',
},
});
// OR use fetch options
const { messages } = useChat({
fetch: (url, options) => {
return fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${token}`,
},
});
},
});
```
---
## 9. React Maximum Update Depth
**Error**: `Maximum update depth exceeded`
**Cause**: Infinite loop in useEffect.
**Solution**:
```tsx
// ❌ BAD: Infinite loop
const saveMessages = (messages) => { /* ... */ };
useEffect(() => {
saveMessages(messages);
}, [messages, saveMessages]); // saveMessages changes every render!
// ✅ GOOD: Only depend on messages
useEffect(() => {
localStorage.setItem('messages', JSON.stringify(messages));
}, [messages]); // saveMessages not needed in deps
```
---
## 10. Repeated Assistant Messages
**Cause**: Duplicate message handling or multiple sendMessage calls.
**Solution**:
```tsx
// ❌ BAD: Calling sendMessage multiple times
const handleSubmit = (e) => {
e.preventDefault();
sendMessage({ content: input });
sendMessage({ content: input }); // Duplicate!
};
// ✅ GOOD: Single call
const handleSubmit = (e) => {
e.preventDefault();
if (!input.trim()) return; // Guard
sendMessage({ content: input });
setInput('');
};
```
---
## 11. onFinish Not Called When Stream Aborted
**Cause**: Stream abort doesn't trigger onFinish callback.
**Solution**:
```tsx
const { stop } = useChat({
onFinish: (message) => {
console.log('Finished:', message);
},
});
// Handle abort separately
const handleStop = () => {
stop();
console.log('Stream aborted by user');
// Do cleanup here
};
```
---
## 12. Type Error with Message Parts (v5)
**Error**: `Property 'parts' does not exist on type 'Message'`
**Cause**: v5 changed message structure for tool calls.
**Solution**:
```tsx
// ✅ CORRECT (v5)
messages.map(message => {
// Use content for simple messages
if (message.content) {
return <div>{message.content}</div>;
}
// Use toolInvocations for tool calls
if (message.toolInvocations) {
return message.toolInvocations.map(tool => (
<div key={tool.toolCallId}>
Tool: {tool.toolName}
</div>
));
}
});
// ❌ WRONG (v4 style)
message.toolCalls // Doesn't exist in v5
```
---
## For More Errors
See complete error reference (28 total types):
https://ai-sdk.dev/docs/reference/ai-sdk-errors
---
**Last Updated**: 2025-10-22