> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usesatori.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Common issues and solutions for Satori integration

## Common Issues

<AccordionGroup>
  <Accordion title="API key not working">
    **Symptoms:**

    * `Unauthorized - Invalid API key` error
    * 401 status code on API requests

    **Solutions:**

    1. **Verify your API key is correct:**

    ```typescript theme={null}
    console.log('API Key:', process.env.SATORI_API_KEY?.substring(0, 15) + '...');
    ```

    2. **Check environment variables are loaded:**

    ```bash theme={null}
    # Make sure .env.local exists
    cat .env.local

    # Restart your development server after adding env vars
    npm run dev
    ```

    3. **Verify the key format:**

    ```typescript theme={null}
    // Should start with 'sk_satori_'
    if (!process.env.SATORI_API_KEY?.startsWith('sk_satori_')) {
      console.error('Invalid API key format');
    }
    ```

    4. **Check if the key is revoked:**

    * Log into your dashboard
    * Go to API Keys
    * Verify the key status is "Active"
  </Accordion>

  <Accordion title="Memories not being saved">
    **Symptoms:**

    * LLM doesn't call `add_item` tool
    * No memories appear in database

    **Solutions:**

    1. **Verify tools are passed to streamText:**

    ```typescript theme={null}
    const tools = memoryTools(config);

    const result = await streamText({
      model: openai('gpt-4o'),
      messages,
      tools, // ← Make sure this is included
    });
    ```

    2. **Check system prompt instructs LLM to save:**

    ```typescript theme={null}
    system: `You are a helpful assistant with memory.

    When the user shares important information, use the add_item tool to save it.
    Important information includes:
    - Personal preferences
    - Personal details
    - Goals and intentions`
    ```

    3. **Verify maxSteps is set:**

    ```typescript theme={null}
    const result = await streamText({
      model: openai('gpt-4o'),
      messages,
      tools,
      maxSteps: 5, // ← Allow tool calls
    });
    ```

    4. **Test with explicit command:**

    ```
    User: "Remember that I love TypeScript"
    ```

    If this doesn't work, check your API logs for errors.
  </Accordion>

  <Accordion title="Context not appearing in responses">
    **Symptoms:**

    * LLM doesn't reference saved memories
    * Responses don't seem personalized

    **Solutions:**

    1. **Verify context is fetched:**

    ```typescript theme={null}
    const context = await getContext(config, userMessage);
    console.log('Memory context:', context);

    // Should output something like:
    // "- User prefers TypeScript
    //  - User loves hiking"
    ```

    2. **Check context is in system prompt:**

    ```typescript theme={null}
    system: `You are a helpful assistant.

    What you know about this user:
    ${memoryContext}  // ← Make sure this is included

    Use this information to personalize responses.`
    ```

    3. **Verify memories exist:**

    ```typescript theme={null}
    const client = new MemoryClient(config);
    const all = await client.getAllMemories();
    console.log('Total memories:', all.length);
    ```

    4. **Check search threshold:**

    ```typescript theme={null}
    // Lower threshold for broader matches
    const context = await getContext(config, userMessage, {
      threshold: 0.6, // Default is 0.7
    });
    ```
  </Accordion>

  <Accordion title="Rate limit exceeded">
    **Symptoms:**

    * `Too Many Requests` error
    * 429 status code

    **Solutions:**

    1. **Implement exponential backoff:**

    ```typescript theme={null}
    async function retryWithBackoff(fn: () => Promise<any>, maxRetries = 3) {
      for (let i = 0; i < maxRetries; i++) {
        try {
          return await fn();
        } catch (error) {
          if (error.message.includes('rate limit') && i < maxRetries - 1) {
            const delay = Math.pow(2, i) * 1000;
            await new Promise(resolve => setTimeout(resolve, delay));
          } else {
            throw error;
          }
        }
      }
    }

    // Usage
    await retryWithBackoff(() => client.addMemory('content'));
    ```

    2. **Batch operations:**

    ```typescript theme={null}
    // Instead of multiple individual calls
    const memories = ['memory1', 'memory2', 'memory3'];
    await Promise.all(memories.map(m => client.addMemory(m)));
    ```

    3. **Cache context fetches:**

    ```typescript theme={null}
    const contextCache = new Map<string, string>();

    async function getCachedContext(query: string) {
      if (contextCache.has(query)) {
        return contextCache.get(query)!;
      }
      
      const context = await getContext(config, query);
      contextCache.set(query, context);
      return context;
    }
    ```

    4. **Contact support for higher limits**
  </Accordion>

  <Accordion title="Slow response times">
    **Symptoms:**

    * API calls take several seconds
    * Chat feels sluggish

    **Solutions:**

    1. **Reduce context limit:**

    ```typescript theme={null}
    // Fetch fewer memories
    const context = await getContext(config, userMessage, {
      limit: 3, // Instead of 10
    });
    ```

    2. **Parallel operations:**

    ```typescript theme={null}
    // Fetch context and start LLM call in parallel
    const [memoryContext] = await Promise.all([
      getContext(config, userMessage),
      // Other async operations
    ]);
    ```

    3. **Cache embeddings for common queries:**

    ```typescript theme={null}
    const embeddingCache = new Map();

    async function getCachedContext(query: string) {
      const cacheKey = query.toLowerCase().trim();
      
      if (embeddingCache.has(cacheKey)) {
        return embeddingCache.get(cacheKey);
      }
      
      const context = await getContext(config, query);
      embeddingCache.set(cacheKey, context);
      
      // Clear cache after 5 minutes
      setTimeout(() => embeddingCache.delete(cacheKey), 5 * 60 * 1000);
      
      return context;
    }
    ```

    4. **Use streaming:**

    ```typescript theme={null}
    // Stream responses for better perceived performance
    const result = await streamText({
      model: openai('gpt-4o'),
      messages,
      tools,
    });

    return result.toDataStreamResponse();
    ```
  </Accordion>

  <Accordion title="TypeScript errors">
    **Symptoms:**

    * Type errors in IDE
    * Build fails with type errors

    **Solutions:**

    1. **Install type definitions:**

    ```bash theme={null}
    npm install --save-dev @types/node
    ```

    2. **Import types correctly:**

    ```typescript theme={null}
    import type { Memory, MemoryWithSimilarity } from '@usesatori/tools';
    ```

    3. **Check tsconfig.json:**

    ```json theme={null}
    {
      "compilerOptions": {
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "moduleResolution": "bundler"
      }
    }
    ```

    4. **Rebuild packages:**

    ```bash theme={null}
    cd packages/js-tools
    npm run build
    ```
  </Accordion>

  <Accordion title="CORS errors">
    **Symptoms:**

    * `CORS policy` error in browser console
    * Requests fail from frontend

    **Solutions:**

    1. **Never call Satori API from frontend:**

    ```typescript theme={null}
    // ❌ Don't do this in client components
    'use client';
    const client = new MemoryClient({ apiKey: '...' }); // API key exposed!

    // ✅ Do this instead - use API routes
    export async function POST(req: Request) {
      // Server-side only
      const client = new MemoryClient({
        apiKey: process.env.SATORI_API_KEY!,
      });
    }
    ```

    2. **Use server-side API routes:**

    ```typescript theme={null}
    // app/api/memories/route.ts
    export async function GET() {
      const client = new MemoryClient({
        apiKey: process.env.SATORI_API_KEY!,
        baseUrl: process.env.SATORI_URL!,
        userId: 'user-123',
      });
      
      const memories = await client.getAllMemories();
      return Response.json({ memories });
    }
    ```
  </Accordion>

  <Accordion title="Memory not found errors">
    **Symptoms:**

    * `Memory not found` when deleting
    * 404 errors

    **Solutions:**

    1. **Verify memory ID:**

    ```typescript theme={null}
    // Make sure you have the correct UUID
    console.log('Deleting memory:', memoryId);
    await client.deleteMemory(memoryId);
    ```

    2. **Check memory belongs to user:**

    ```typescript theme={null}
    // Memory IDs are scoped per user
    const memories = await client.getAllMemories();
    const exists = memories.some(m => m.id === memoryId);

    if (!exists) {
      console.error('Memory not found for this user');
    }
    ```

    3. **Handle errors gracefully:**

    ```typescript theme={null}
    try {
      await client.deleteMemory(memoryId);
    } catch (error) {
      if (error.message.includes('Not Found')) {
        console.log('Memory already deleted or does not exist');
      } else {
        throw error;
      }
    }
    ```
  </Accordion>

  <Accordion title="Duplicate memories">
    **Symptoms:**

    * Same information saved multiple times
    * Too many similar memories

    **Solutions:**

    1. **Check before saving:**

    ```typescript theme={null}
    // Search for similar memories first
    const existing = await client.searchMemories(content, {
      threshold: 0.9, // High threshold for near-duplicates
      limit: 1,
    });

    if (existing.length === 0) {
      await client.addMemory(content);
    } else {
      console.log('Similar memory already exists');
    }
    ```

    2. **Update system prompt:**

    ```typescript theme={null}
    system: `Before saving a memory, consider if similar information already exists.
    Only save truly new or updated information.`
    ```

    3. **Periodic cleanup:**

    ```typescript theme={null}
    // Find and merge duplicate memories
    const memories = await client.getAllMemories();

    for (let i = 0; i < memories.length; i++) {
      for (let j = i + 1; j < memories.length; j++) {
        const similarity = await calculateSimilarity(
          memories[i].content,
          memories[j].content
        );
        
        if (similarity > 0.95) {
          // Keep the newer one, delete the older
          await client.deleteMemory(memories[i].id);
          break;
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Debugging Tips

### Enable Verbose Logging

```typescript theme={null}
// Add detailed logging
console.log('=== Memory Debug Info ===');
console.log('User ID:', userId);
console.log('API Key:', process.env.SATORI_API_KEY?.substring(0, 15) + '...');
console.log('Base URL:', process.env.SATORI_URL);

const context = await getContext(config, userMessage);
console.log('Context fetched:', context);
console.log('Context length:', context.length);

const result = await streamText({
  model: openai('gpt-4o'),
  system: `...${context}`,
  messages,
  tools,
  onFinish: (result) => {
    console.log('Tool calls:', result.toolCalls);
    console.log('Finish reason:', result.finishReason);
  },
});
```

### Test Memory Operations Directly

```typescript theme={null}
// Test script to verify memory operations
import { MemoryClient } from '@usesatori/tools';

async function testMemory() {
  const client = new MemoryClient({
    apiKey: process.env.SATORI_API_KEY!,
    baseUrl: process.env.SATORI_URL!,
    userId: 'test-user',
  });
  
  console.log('1. Adding memory...');
  const memory = await client.addMemory('Test memory content');
  console.log('✓ Memory added:', memory.id);
  
  console.log('2. Searching memories...');
  const results = await client.searchMemories('test');
  console.log('✓ Found', results.length, 'memories');
  
  console.log('3. Getting all memories...');
  const all = await client.getAllMemories();
  console.log('✓ Total memories:', all.length);
  
  console.log('4. Deleting memory...');
  await client.deleteMemory(memory.id);
  console.log('✓ Memory deleted');
  
  console.log('All tests passed!');
}

testMemory().catch(console.error);
```

### Check Network Requests

```typescript theme={null}
// Log all fetch requests
const originalFetch = global.fetch;
global.fetch = async (...args) => {
  console.log('Fetch:', args[0]);
  const response = await originalFetch(...args);
  console.log('Status:', response.status);
  return response;
};
```

## Getting Help

If you're still experiencing issues:

<CardGroup cols={2}>
  <Card title="Check Documentation" icon="book" href="/quickstart">
    Review the quickstart guide
  </Card>

  <Card title="GitHub Issues" icon="github" href="https://github.com/yourusername/satori/issues">
    Report bugs or request features
  </Card>

  <Card title="Community Discord" icon="discord" href="https://discord.gg/satori">
    Get help from the community
  </Card>

  <Card title="Email Support" icon="envelope" href="mailto:support@satori.dev">
    Contact our support team
  </Card>
</CardGroup>

## Useful Resources

* [API Reference](/api-reference/introduction)
* [Integration Guides](/guides/vercel-ai-sdk)
* [Core Concepts](/concepts/how-it-works)
* [Examples](/examples/chat-with-memory)
