Files
2025-11-30 08:25:15 +08:00

447 lines
13 KiB
Markdown

# Top 12 Errors - OpenAI Assistants API
**Last Updated**: 2025-10-25
This document catalogs the most common errors encountered when working with the Assistants API v2 and their solutions.
---
## 1. Thread Already Has Active Run
**Error Message**:
```
Error: 400 Can't add messages to thread_xxx while a run run_xxx is active.
```
**Cause**: Trying to create a new run or add messages while another run is still processing (status: `queued`, `in_progress`, or `cancelling`).
**Solution**:
```typescript
async function ensureNoActiveRun(threadId: string) {
const runs = await openai.beta.threads.runs.list(threadId, {
limit: 1,
order: 'desc',
});
const latestRun = runs.data[0];
if (latestRun && ['queued', 'in_progress', 'cancelling'].includes(latestRun.status)) {
// Wait for completion or cancel
await openai.beta.threads.runs.cancel(threadId, latestRun.id);
// Poll until cancelled
let run = latestRun;
while (run.status !== 'cancelled') {
await new Promise(resolve => setTimeout(resolve, 500));
run = await openai.beta.threads.runs.retrieve(threadId, run.id);
}
}
}
```
**Prevention**: Always check for active runs before creating new ones.
**Source**: [OpenAI Community](https://community.openai.com/t/error-running-thread-already-has-an-active-run/782118)
---
## 2. Run Polling Timeout
**Error**: Run never completes within reasonable polling window (300+ seconds).
**Cause**: Long-running tasks (complex code execution, large file processing) exceed expected completion time.
**Solution**:
```typescript
async function pollWithTimeout(threadId: string, runId: string, maxSeconds = 300) {
const startTime = Date.now();
while (true) {
const run = await openai.beta.threads.runs.retrieve(threadId, runId);
if (!['queued', 'in_progress'].includes(run.status)) {
return run;
}
const elapsed = (Date.now() - startTime) / 1000;
if (elapsed > maxSeconds) {
await openai.beta.threads.runs.cancel(threadId, runId);
throw new Error(`Run exceeded timeout of ${maxSeconds}s`);
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
```
**Prevention**: Set appropriate timeouts and use streaming for better UX.
---
## 3. Vector Store Indexing Delay
**Error**: File search returns no results despite files being uploaded.
**Cause**: Using vector store before indexing completes (async process).
**Solution**:
```typescript
async function waitForVectorStore(vectorStoreId: string) {
let store = await openai.beta.vectorStores.retrieve(vectorStoreId);
while (store.status === 'in_progress') {
await new Promise(resolve => setTimeout(resolve, 2000));
store = await openai.beta.vectorStores.retrieve(vectorStoreId);
console.log(`Indexing: ${store.file_counts.completed}/${store.file_counts.total}`);
}
if (store.status === 'failed') {
throw new Error('Vector store indexing failed');
}
return store; // status: 'completed'
}
```
**Prevention**: Always wait for `status: "completed"` before using vector store with assistants.
**Source**: [OpenAI Community](https://community.openai.com/t/assistants-api-file-search-and-vector-stores/863944)
---
## 4. File Search Relevance Issues
**Error**: File search returns irrelevant or incomplete results.
**Cause**: Poor document chunking, lack of context, or query optimization needed.
**Solution**:
- **Better instructions**: Guide assistant on how to use file search
- **Structured documents**: Use clear headers, sections, and formatting
- **Metadata**: Add descriptive metadata to files (coming soon)
- **Query refinement**: Encourage users to be specific
```typescript
const assistant = await openai.beta.assistants.create({
instructions: `You are a support assistant. When answering:
1. Use file_search to find relevant documentation
2. Quote specific sections with citations
3. If information isn't found, say so clearly
4. Provide context around the answer`,
tools: [{ type: "file_search" }],
// ...
});
```
**Prevention**: Structure documents well and provide clear assistant instructions.
---
## 5. Code Interpreter File Output Not Found
**Error**: `image_file.file_id` referenced but file doesn't exist or can't be downloaded.
**Cause**: Files generated by Code Interpreter are temporary and may be cleaned up before retrieval.
**Solution**:
```typescript
// Retrieve and save immediately after run completes
const messages = await openai.beta.threads.messages.list(threadId);
const responseMessage = messages.data[0];
for (const content of responseMessage.content) {
if (content.type === 'image_file') {
try {
const fileData = await openai.files.content(content.image_file.file_id);
const buffer = Buffer.from(await fileData.arrayBuffer());
fs.writeFileSync(`output_${content.image_file.file_id}.png`, buffer);
} catch (error) {
console.error('File no longer available:', error);
}
}
}
```
**Prevention**: Download generated files immediately after run completion.
**Source**: [Medium - Code Interpreter Tutorial](https://tmmtt.medium.com/openai-assistant-api-with-code-interpreter-e7f382bff83e)
---
## 6. Thread Message Limit Exceeded
**Error**: `400 Thread has exceeded the maximum number of messages (100,000)`.
**Cause**: Very long conversations hitting the 100k message limit.
**Solution**:
```typescript
async function archiveAndStartNewThread(oldThreadId: string, userId: string) {
// Get conversation summary
const messages = await openai.beta.threads.messages.list(oldThreadId, {
limit: 50,
});
// Save to database
await db.archiveThread(oldThreadId, messages.data);
// Create new thread
const newThread = await openai.beta.threads.create({
metadata: {
user_id: userId,
previous_thread: oldThreadId,
},
});
return newThread.id;
}
```
**Prevention**: Archive old threads and create new ones periodically.
---
## 7. Function Calling Timeout
**Error**: Run expires (status: `expired`) while waiting for tool outputs.
**Cause**: Tool execution takes too long (max 10 minutes for run).
**Solution**:
```typescript
if (run.status === 'requires_action') {
const toolCalls = run.required_action.submit_tool_outputs.tool_calls;
const toolOutputs = [];
for (const toolCall of toolCalls) {
try {
// Add timeout to function execution
const output = await Promise.race([
executeFunction(toolCall.function.name, JSON.parse(toolCall.function.arguments)),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Function timeout')), 30000)
),
]);
toolOutputs.push({
tool_call_id: toolCall.id,
output: JSON.stringify(output),
});
} catch (error) {
// Return error as output
toolOutputs.push({
tool_call_id: toolCall.id,
output: JSON.stringify({ error: error.message }),
});
}
}
await openai.beta.threads.runs.submitToolOutputs(threadId, run.id, {
tool_outputs: toolOutputs,
});
}
```
**Prevention**: Implement timeouts on function execution and return errors gracefully.
---
## 8. Streaming Run Interruption
**Error**: Stream connection closes unexpectedly or events stop arriving.
**Cause**: Network issues, server errors, or run failures.
**Solution**:
```typescript
async function streamWithRetry(threadId: string, assistantId: string) {
try {
const stream = await openai.beta.threads.runs.stream(threadId, {
assistant_id: assistantId,
});
for await (const event of stream) {
// Handle events
if (event.event === 'error') {
throw new Error('Stream error');
}
}
} catch (error) {
console.error('Stream interrupted:', error);
// Fall back to polling
const runs = await openai.beta.threads.runs.list(threadId, {
limit: 1,
order: 'desc',
});
const run = runs.data[0];
return pollRunCompletion(threadId, run.id);
}
}
```
**Prevention**: Implement fallback to polling if streaming fails.
**Source**: [OpenAI Community](https://community.openai.com/t/streaming-stopped-at-thread-run-requires-action-when-handling-openai-assistants-function-calling/943674)
---
## 9. Vector Store Quota Limits
**Error**: `429 Rate limit reached for vector store operations`.
**Cause**: Too many vector store operations or storage exceeded.
**Solution**:
- **Monitor storage**: Check `usage_bytes` regularly
- **Delete unused stores**: Clean up old vector stores
- **Batch operations**: Use batch file uploads instead of individual uploads
```typescript
async function cleanupOldVectorStores(keepDays = 30) {
const stores = await openai.beta.vectorStores.list({ limit: 100 });
for (const store of stores.data) {
const ageSeconds = Date.now() / 1000 - store.created_at;
const ageDays = ageSeconds / (60 * 60 * 24);
if (ageDays > keepDays) {
await openai.beta.vectorStores.del(store.id);
console.log(`Deleted vector store: ${store.id}`);
}
}
}
```
**Prevention**: Set auto-expiration on vector stores and monitor costs.
---
## 10. File Upload Format Incompatibility
**Error**: `400 Unsupported file type for this tool`.
**Cause**: Uploading file format not supported by the tool.
**Solution**:
```typescript
const SUPPORTED_FORMATS = {
code_interpreter: [
'.c', '.cpp', '.csv', '.docx', '.html', '.java', '.json', '.md',
'.pdf', '.php', '.pptx', '.py', '.rb', '.tex', '.txt', '.css',
'.jpeg', '.jpg', '.js', '.gif', '.png', '.tar', '.ts', '.xlsx', '.xml', '.zip'
],
file_search: [
'.c', '.cpp', '.docx', '.html', '.java', '.json', '.md',
'.pdf', '.php', '.pptx', '.py', '.rb', '.tex', '.txt', '.css', '.js', '.ts', '.go'
],
};
function validateFileFormat(filename: string, tool: 'code_interpreter' | 'file_search') {
const ext = filename.substring(filename.lastIndexOf('.')).toLowerCase();
if (!SUPPORTED_FORMATS[tool].includes(ext)) {
throw new Error(`Unsupported file format for ${tool}: ${ext}`);
}
}
// Validate before upload
validateFileFormat('data.csv', 'code_interpreter'); // OK
validateFileFormat('video.mp4', 'file_search'); // Throws error
```
**Prevention**: Validate file formats before uploading.
---
## 11. Assistant Instructions Token Limit
**Error**: `400 Instructions exceed maximum length`.
**Cause**: Instructions field exceeds 256,000 characters (v2 limit).
**Solution**:
- **Use file search**: Put long instructions in documents
- **Concise instructions**: Be clear and brief
- **System messages**: Use thread-level messages for context
```typescript
// ❌ Bad: Very long instructions
const assistant = await openai.beta.assistants.create({
instructions: "..." // 300k characters
});
// ✅ Good: Concise instructions + file search
const assistant = await openai.beta.assistants.create({
instructions: "You are a support assistant. Use file_search to find answers in the knowledge base.",
tools: [{ type: "file_search" }],
tool_resources: {
file_search: {
vector_store_ids: [vectorStoreId], // Long content here
},
},
});
```
**Prevention**: Keep instructions under 256k characters; use file search for knowledge.
---
## 12. Thread Deletion While Run Active
**Error**: `400 Cannot delete thread while run is active`.
**Cause**: Attempting to delete a thread that has an active run.
**Solution**:
```typescript
async function safeDeleteThread(threadId: string) {
// Cancel active runs first
const runs = await openai.beta.threads.runs.list(threadId);
for (const run of runs.data) {
if (['queued', 'in_progress'].includes(run.status)) {
await openai.beta.threads.runs.cancel(threadId, run.id);
// Wait for cancellation
let runStatus = run;
while (runStatus.status !== 'cancelled') {
await new Promise(resolve => setTimeout(resolve, 500));
runStatus = await openai.beta.threads.runs.retrieve(threadId, run.id);
}
}
}
// Now safe to delete
await openai.beta.threads.del(threadId);
}
```
**Prevention**: Cancel all active runs before deleting threads.
---
## Quick Reference
| Error | Quick Fix |
|-------|-----------|
| Thread has active run | Cancel or wait for run completion |
| Polling timeout | Set timeout and cancel long runs |
| Vector store not ready | Wait for `status: "completed"` |
| File search no results | Check indexing complete, improve queries |
| Code Interpreter file lost | Download immediately after run |
| 100k message limit | Archive old threads, start new ones |
| Function timeout | Add timeouts to function execution |
| Stream interrupted | Fall back to polling |
| Vector store quota | Clean up old stores, use batch uploads |
| Unsupported file format | Validate file extensions before upload |
| Instructions too long | Use file search for knowledge |
| Can't delete thread | Cancel active runs first |
---
**Additional Resources**:
- [OpenAI Assistants API Docs](https://platform.openai.com/docs/assistants)
- [OpenAI Community Forum](https://community.openai.com/c/api/assistants-api/49)
- [API Reference](https://platform.openai.com/docs/api-reference/assistants)