> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/darkzOGx/youtube-automation-agent/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Debug and resolve common issues with the YouTube Automation Agent

## Overview

This guide helps you identify and resolve common issues. The system includes comprehensive logging and error handling based on patterns from `utils/logger.js` and error handling throughout the codebase.

## Logging System

### Understanding Log Levels

The system uses Winston logging with multiple levels (from `utils/logger.js:14-20`):

```javascript theme={null}
// Set log level in .env
LOG_LEVEL=info  // Options: error, warn, info, debug
```

<AccordionGroup>
  <Accordion title="ERROR - Critical failures">
    System errors that prevent normal operation. Always logged to `logs/error.log`.

    ```bash theme={null}
    [ERROR] [ContentStrategy] Failed to fetch YouTube trends: API quota exceeded
    ```
  </Accordion>

  <Accordion title="WARN - Potential issues">
    Non-critical issues that should be monitored.

    ```bash theme={null}
    [WARN] [ScriptWriter] No historical data found, starting fresh
    ```
  </Accordion>

  <Accordion title="INFO - Normal operations">
    Standard operational messages.

    ```bash theme={null}
    [INFO] [MainAgent] ✓ strategy agent initialized
    ```
  </Accordion>

  <Accordion title="DEBUG - Detailed diagnostics">
    Detailed information for troubleshooting. Only shown in development.

    ```bash theme={null}
    [DEBUG] [Database] Executing query: SELECT * FROM productions
    ```
  </Accordion>
</AccordionGroup>

### Log Files Location

Logs are stored in separate files (from `utils/logger.js:23-43`):

```bash theme={null}
logs/
├── combined.log          # All logs (max 5MB × 5 files)
├── error.log            # Errors only (max 5MB × 3 files)
├── mainalent.log        # Main agent logs
├── contentstrategy.log  # Strategy agent logs
├── scriptwriter.log     # Script writer logs
└── [component].log      # Component-specific logs
```

### Viewing Logs

```bash theme={null}
# View all recent logs
tail -f logs/combined.log

# View errors only
tail -f logs/error.log

# View specific agent logs
tail -f logs/contentstrategy.log

# Search for specific errors
grep "Failed" logs/combined.log

# View last 100 lines with context
tail -n 100 logs/combined.log
```

## Common Issues

### Authentication Failures

#### YouTube API Authentication Error

**Symptoms:**

```bash theme={null}
[ERROR] [CredentialManager] YouTube credentials not configured
[ERROR] Failed to initialize: YouTube authentication required
```

**Solutions:**

<Steps>
  <Step title="Verify credentials file exists">
    ```bash theme={null}
    ls -la config/credentials.json
    ls -la config/tokens.json
    ```
  </Step>

  <Step title="Check credentials format">
    Ensure `config/credentials.json` matches the example from `config/credentials.example.json:1-32`:

    ```json theme={null}
    {
      "youtube": {
        "client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
        "client_secret": "YOUR_CLIENT_SECRET",
        "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob"]
      },
      "openai": {
        "apiKey": "sk-...",
        "model": "gpt-4-turbo-preview"
      }
    }
    ```
  </Step>

  <Step title="Re-authenticate">
    ```bash theme={null}
    npm run credentials:setup
    ```

    Follow the prompts to re-authenticate with YouTube.
  </Step>

  <Step title="Verify API is enabled">
    * Go to Google Cloud Console
    * Enable YouTube Data API v3
    * Enable YouTube Analytics API
  </Step>
</Steps>

#### Token Expired

**Symptoms:**

```bash theme={null}
[ERROR] Invalid Credentials: Request had invalid authentication credentials
```

**Solution:**

Tokens automatically refresh, but if they're corrupted:

```bash theme={null}
# Delete old tokens
rm config/tokens.json

# Re-authenticate
node utils/credential-manager.js setup
```

### Database Issues

#### Database Locked

**Symptoms:**

```bash theme={null}
[ERROR] [Database] SQLITE_BUSY: database is locked
```

**Solutions:**

1. **Check for multiple instances:**

```bash theme={null}
# Check if agent is already running
ps aux | grep "node index.js"

# Kill existing processes
kill [PID]
```

2. **Close database connections:**

```javascript theme={null}
// Properly close database before restart
const agent = new YouTubeAutomationAgent();
await agent.db.close();
```

3. **Database corruption:**

```bash theme={null}
# Check database integrity
sqlite3 data/youtube_automation.db "PRAGMA integrity_check;"

# If corrupted, restore from backup
cp data/backup_[timestamp].db data/youtube_automation.db
```

#### Missing Tables

**Symptoms:**

```bash theme={null}
[ERROR] no such table: content_strategies
```

**Solution:**

Reinitialize database (from `database/db.js:33-195`):

```bash theme={null}
# Delete and recreate
rm data/youtube_automation.db
node index.js

# Or manually initialize
node -e "const {Database} = require('./database/db'); const db = new Database(); db.initialize();"
```

### Content Generation Failures

#### Script Generation Timeout

**Symptoms:**

```bash theme={null}
[ERROR] [ScriptWriter] Failed to generate script: Request timeout
```

**Solutions:**

1. **Increase timeout in environment:**

```bash .env theme={null}
OPENAI_TIMEOUT=120000  # 2 minutes
```

2. **Check OpenAI API status:**

```bash theme={null}
curl https://status.openai.com/api/v2/status.json
```

3. **Implement retry logic:**

```javascript theme={null}
const RETRY_ATTEMPTS = 3;
const RETRY_DELAY = 5000;

for (let attempt = 1; attempt <= RETRY_ATTEMPTS; attempt++) {
  try {
    const script = await this.agents.scriptWriter.generateScript(strategy);
    break;
  } catch (error) {
    if (attempt === RETRY_ATTEMPTS) throw error;
    await new Promise(resolve => setTimeout(resolve, RETRY_DELAY));
    this.logger.warn(`Retry attempt ${attempt}/${RETRY_ATTEMPTS}`);
  }
}
```

#### AI Model Quota Exceeded

**Symptoms:**

```bash theme={null}
[ERROR] OpenAI API error: Rate limit exceeded
```

**Solutions:**

<Steps>
  <Step title="Check your OpenAI quota">
    Visit [https://platform.openai.com/account/usage](https://platform.openai.com/account/usage)
  </Step>

  <Step title="Implement rate limiting">
    ```javascript theme={null}
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

    // Add delay between API calls
    await delay(2000); // 2 second delay
    ```
  </Step>

  <Step title="Switch to cheaper model temporarily">
    ```json config/credentials.json theme={null}
    {
      "openai": {
        "apiKey": "sk-...",
        "model": "gpt-3.5-turbo"  // Instead of gpt-4
      }
    }
    ```
  </Step>
</Steps>

### Publishing Issues

#### Upload Failed

**Symptoms:**

```bash theme={null}
[ERROR] [PublishingScheduling] Failed to upload video: Quota exceeded
```

**YouTube API Quota Information:**

* **Daily quota:** 10,000 units
* **Video upload:** \~1,600 units
* **Video update:** 50 units
* **Analytics:** 1 unit per request

**Solutions:**

1. **Monitor quota usage:**

```javascript theme={null}
// Add quota tracking
async trackQuotaUsage(operation, cost) {
  const today = new Date().toISOString().split('T')[0];
  const used = await this.db.getSetting(`quota_${today}`) || 0;
  const newUsed = parseInt(used) + cost;
  
  await this.db.setSetting(`quota_${today}`, newUsed.toString());
  
  if (newUsed > 9000) {
    this.logger.warn(`Approaching quota limit: ${newUsed}/10,000`);
  }
}
```

2. **Implement queue system:**

```javascript theme={null}
// Spread uploads throughout the day
if (quotaRemaining < 1600) {
  await this.db.updateScheduleEntry({
    ...entry,
    status: 'paused',
    error: 'Quota limit - will retry tomorrow'
  });
}
```

#### Video Processing Stuck

**Symptoms:**

```bash theme={null}
[WARN] Video uploaded but still processing after 30 minutes
```

**Solution:**

```javascript theme={null}
// Implement processing check
async checkVideoProcessingStatus(videoId) {
  const youtube = this.credentials.getYouTubeClient();
  
  const response = await youtube.videos.list({
    part: 'status,processingDetails',
    id: videoId
  });
  
  const video = response.data.items[0];
  
  if (video.status.uploadStatus === 'processed') {
    return 'complete';
  } else if (video.status.uploadStatus === 'failed') {
    throw new Error(`Processing failed: ${video.status.failureReason}`);
  }
  
  return 'processing';
}
```

### Scheduler Issues

#### Cron Jobs Not Running

**Symptoms:**

```bash theme={null}
[INFO] Scheduled task created but content not generating
```

**Debug steps:**

```javascript schedules/daily-automation.js theme={null}
// Add debugging to scheduler
async setupScheduledTasks() {
  this.scheduledTasks.set('daily-content-generation', 
    cron.schedule('0 6 * * *', async () => {
      console.log('CRON TRIGGERED:', new Date().toISOString());
      
      if (this.isEnabled) {
        console.log('Running daily generation...');
        await this.runDailyContentGeneration();
      } else {
        console.log('Automation disabled, skipping');
      }
    }, { 
      scheduled: true,
      timezone: 'America/New_York' // Set your timezone
    })
  );
  
  // Verify task is scheduled
  this.scheduledTasks.forEach((task, name) => {
    console.log(`Task ${name}:`, task.options);
  });
}
```

**Test scheduler:**

```javascript theme={null}
// Test with shorter interval
cron.schedule('*/1 * * * *', async () => {
  console.log('Test task running every minute');
});
```

### Performance Issues

#### High Memory Usage

**Symptoms:**

```bash theme={null}
[WARN] System health score: 65/100
memory: { heapUsed: 950MB, heapTotal: 1024MB }
```

**Solutions:**

1. **Monitor memory:**

```javascript theme={null}
const logMemoryUsage = () => {
  const used = process.memoryUsage();
  console.log('Memory Usage:');
  for (let key in used) {
    console.log(`  ${key}: ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`);
  }
};

setInterval(logMemoryUsage, 60000); // Every minute
```

2. **Clear caches:**

```javascript theme={null}
// Clear agent caches periodically
async clearCaches() {
  this.agents.strategy.trendingTopics = [];
  this.agents.strategy.competitorData = [];
  
  if (global.gc) {
    global.gc();
    this.logger.info('Garbage collection triggered');
  }
}
```

3. **Limit concurrent operations:**

```javascript theme={null}
// Process in batches instead of all at once
const batchSize = 5;
for (let i = 0; i < items.length; i += batchSize) {
  const batch = items.slice(i, i + batchSize);
  await Promise.all(batch.map(item => processItem(item)));
  await new Promise(resolve => setTimeout(resolve, 1000)); // Pause between batches
}
```

#### Slow Response Times

**Debug with performance logging:**

```javascript theme={null}
// Use built-in timer (from logger.js:104-113)
const timer = this.logger.startTimer('Content Generation Pipeline');

const strategy = await this.agents.strategy.generateContentStrategy();
const t1 = this.logger.startTimer('Strategy');
t1.end(); // Logs: "Strategy completed in Xms"

const script = await this.agents.scriptWriter.generateScript(strategy);
const t2 = this.logger.startTimer('Script');
t2.end();

timer.end(); // Logs total pipeline time
```

## Error Recovery

### Automatic Retry Pattern

Implement throughout your code:

```javascript utils/retry-helper.js theme={null}
class RetryHelper {
  static async withRetry(fn, options = {}) {
    const {
      maxAttempts = 3,
      delayMs = 5000,
      backoff = true,
      onRetry = null
    } = options;
    
    let lastError;
    
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      try {
        return await fn();
      } catch (error) {
        lastError = error;
        
        if (attempt === maxAttempts) {
          throw error;
        }
        
        const delay = backoff ? delayMs * attempt : delayMs;
        
        if (onRetry) {
          onRetry(attempt, maxAttempts, error);
        }
        
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
    
    throw lastError;
  }
}

// Usage:
const result = await RetryHelper.withRetry(
  () => this.agents.strategy.generateContentStrategy(),
  {
    maxAttempts: 3,
    delayMs: 5000,
    backoff: true,
    onRetry: (attempt, max, error) => {
      this.logger.warn(`Retry ${attempt}/${max}: ${error.message}`);
    }
  }
);
```

### Graceful Degradation

```javascript theme={null}
// Fallback to simpler operations if primary fails
async generateContentWithFallback(topic) {
  try {
    // Try with GPT-4
    return await this.generateWithModel('gpt-4-turbo-preview', topic);
  } catch (error) {
    this.logger.warn('GPT-4 failed, falling back to GPT-3.5');
    
    try {
      // Fallback to GPT-3.5
      return await this.generateWithModel('gpt-3.5-turbo', topic);
    } catch (fallbackError) {
      this.logger.error('All models failed, using template');
      // Ultimate fallback to template
      return this.generateFromTemplate(topic);
    }
  }
}
```

## Health Monitoring

### System Health Check

The automation includes health monitoring (from `schedules/daily-automation.js:476-526`):

```javascript theme={null}
// Access health endpoint
curl http://localhost:3456/health

// Response:
{
  "status": "healthy",
  "initialized": true,
  "agents": ["strategy", "scriptWriter", ...],
  "timestamp": "2026-03-05T10:30:00.000Z"
}
```

### Custom Health Checks

```javascript theme={null}
async performDetailedHealthCheck() {
  const health = {
    database: await this.checkDatabase(),
    youtube: await this.checkYouTubeAPI(),
    openai: await this.checkOpenAI(),
    disk: await this.checkDiskSpace(),
    memory: this.checkMemory()
  };
  
  const issues = Object.entries(health)
    .filter(([, status]) => !status.healthy)
    .map(([component, status]) => `${component}: ${status.error}`);
  
  if (issues.length > 0) {
    this.logger.error('Health check failed:', issues);
    // Send alert notification
    await this.sendAlert('System Health Issues', issues.join('\n'));
  }
  
  return health;
}

async checkDatabase() {
  try {
    await this.db.getAllRows('SELECT 1');
    return { healthy: true };
  } catch (error) {
    return { healthy: false, error: error.message };
  }
}

async checkYouTubeAPI() {
  try {
    const youtube = this.credentials.getYouTubeClient();
    await youtube.channels.list({ part: 'snippet', mine: true });
    return { healthy: true };
  } catch (error) {
    return { healthy: false, error: error.message };
  }
}

async checkDiskSpace() {
  const { execSync } = require('child_process');
  const output = execSync('df -h /').toString();
  const usage = parseInt(output.split('\n')[1].split(/\s+/)[4]);
  
  return {
    healthy: usage < 90,
    usage: `${usage}%`,
    error: usage >= 90 ? 'Disk space critical' : null
  };
}
```

<Warning>
  **Critical Issues Requiring Immediate Attention:**

  * Database corruption
  * API authentication failures
  * Disk space > 90% full
  * Memory usage > 90%
  * Continuous failed content generation
  * YouTube quota consistently exceeded
</Warning>

## Getting Help

### Collecting Diagnostic Information

When reporting issues:

```bash theme={null}
# Collect system info
node -v
npm -v
uname -a

# Check package versions
cat package.json | grep version

# Recent errors
tail -n 50 logs/error.log

# Database stats
sqlite3 data/youtube_automation.db "SELECT name, value FROM settings;"

# Disk usage
du -sh data/ logs/
```

### Debug Mode

Run in debug mode:

```bash theme={null}
LOG_LEVEL=debug NODE_ENV=development node index.js
```

<CardGroup cols={2}>
  <Card title="Customization" icon="wrench" href="/advanced/customization">
    Customize and extend the system
  </Card>

  <Card title="Configuration" icon="gear" href="/configuration/getting-api-keys">
    Review configuration options
  </Card>
</CardGroup>
