# Product Updates Troubleshooting Guide

**Last Updated**: 2025-11-20  
**Status**: Production Ready ✅

## Overview

This guide provides solutions for common issues encountered when working with the Product Updates CMS system. Each issue includes symptoms, causes, and step-by-step solutions.

## Quick Diagnostic Checklist

Before diving into specific issues, run these quick checks:

1. **Storage Health Check**:

   ```
   GET /v2/api/produkt-updates-storage-health.php
   ```

2. **Comprehensive Test**:

   ```
   GET /v2/admin/produkt-updates/comprehensive-production-test.php?password=...
   ```

3. **Check Error Logs**:
   - PHP error log
   - Storage log: `v2/logs/produkt-updates-storage.log`
   - Admin log: `v2/logs/produkt_updates_admin_YYYY-MM-DD.log`

## Common Issues

### Issue 1: HTTP 500 Error When Adding Improvements

**Symptoms**:

- Browser shows "HTTP ERROR 500" page when submitting "Add Improvement" form
- Improvement is not saved
- No error message displayed to user
- Error occurs with all fields filled or specific field combinations

**Causes**:

- Uncaught exceptions in `add_improvement` handler
- Invalid redirect URL causing header failure
- Output buffer issues (headers sent after output)
- Missing error handling causing fatal errors
- Data validation failures
- `regenerateMonthsFromContent()` throwing exceptions
- `sanitizeHtmlInput()` failing on malformed HTML
- Invalid `published_date` format or empty date handling

**Solutions**:

1. **Check Error Logs**:

   Check PHP error log and custom log files:
   ```
   v2/logs/produkt_updates_admin_YYYY-MM-DD.log
   ```

   Look for error entries with error IDs (format: `add_imp_*`)

2. **Run Diagnostic Test**:

   ```
   GET /v2/admin/produkt-updates/test-add-improvement.php?test=all
   ```

   This will test various input scenarios and identify failing cases.

3. **Check Error Context**:

   Errors are logged with full context including:
   - POST data (sanitized)
   - Stack trace
   - File paths
   - Timestamp, user agent, IP address
   - Error ID for tracking

4. **Verify Backups**:

   Automatic backups are created before each save. Check:
   ```
   v2/data/backups/produkt_updates_YYYY-MM-DD_HHMMSS.json
   ```

5. **Common Fixes**:

   - **Empty published_date**: System now provides default (current date) if empty
   - **Invalid date format**: Must be YYYY-MM-DD format
   - **Future dates**: Not allowed - use current or past date
   - **Malformed HTML**: Automatically sanitized with fallback to plain text
   - **Long titles**: Maximum 200 characters enforced
   - **Empty description**: Validated and rejected with user-friendly error

6. **Manual Testing**:

   Test these scenarios:
   - All fields filled with valid data
   - Empty published_date (should use default)
   - Invalid date format
   - Future date
   - Empty title
   - Empty description
   - Very long title (>200 chars)
   - Malformed HTML in description
   - Special characters in title/description

**Error Codes**:

- `add_imp_*`: Error ID for tracking specific failures
- Check logs for full error context and stack trace

**Prevention**:

- All inputs are validated before processing
- Comprehensive error handling with try-catch blocks
- Automatic backups before each save
- Detailed error logging for debugging
- User-friendly error messages displayed instead of 500 errors

**Related Files**:

- `v2/pages/produkt_updates_admin.php` - Main handler (lines ~2759-2950)
- `v2/admin/produkt-updates/test-add-improvement.php` - Test script
- `v2/api/produkt-updates-diagnostics.php` - Diagnostic endpoint

---

### Issue 2: Featured Images Become Unlinked from Features

**Symptoms**:

- Featured images periodically become unlinked from feature entries
- Occurs every 1-2 weeks, possibly after server restarts
- Images still exist in WordPress folder and admin image library
- Images can be re-linked manually but become unlinked again
- All features lose their featured_image associations simultaneously

**Root Cause**:

The `migrateImagesToFeaturedImage()` function was using `empty()` check which treats empty strings as "missing":

```php
if (!isset($feature['featured_image']) || empty($feature['featured_image'])) {
```

**Critical Bug**: `empty()` returns `true` for empty strings (`''`). This caused:
1. If `featured_image` exists but is empty string, migration treats it as "missing"
2. Migration function runs on EVERY page load (line 452)
3. After server restart, path resolution mismatch causes data to be read from different location
4. Migration overwrites existing fields with empty strings
5. This gets saved, permanently losing image associations

**Additional Contributing Factors**:
- Path resolution mismatch: `findReadableDataFile()` vs `findWritableDataFile()` returning different locations
- Data reload after POST using `findReadableDataFile()` instead of writable location
- No validation to prevent saving when `featured_image` fields are lost
- Migration running on every page load instead of once

**Solutions**:

1. **Fixed Migration Logic** (CRITICAL FIX):

   The migration function now only checks `!isset()`, never `empty()`:
   ```php
   if (!isset($feature['featured_image'])) {
       // Only migrate if field truly doesn't exist
   }
   ```
   
   This prevents overwriting existing `featured_image` fields, even if they're empty strings.

2. **Migration Flag Added**:

   A `migration_complete` flag prevents re-migration on every page load:
   ```php
   if (!isset($updates_data['migration_complete']) || $updates_data['migration_complete'] !== true) {
       migrateImagesToFeaturedImage($updates_data);
   }
   ```

3. **Path Resolution Fixed**:

   - Data reload after POST now uses `findWritableDataFile()` instead of `findReadableDataFile()`
   - Path validation ensures read/write locations match when possible
   - Logging added for path mismatches

4. **Save Prevention**:

   `saveUpdatesData()` now FAILS if `featured_image` fields would be lost:
   ```php
   if ($featured_image_count_after < $featured_image_count_before) {
       return false; // Prevent save
   }
   ```

5. **Recovery Tools**:

   - **Recovery Script**: `/v2/admin/produkt-updates/recover-featured-images.php?action=recover`
     - Scans backups for `featured_image` values
     - Restores missing fields
     - Validates image files exist before restoring
   
   - **Monitoring Script**: `/v2/admin/produkt-updates/monitor-featured-images.php`
     - Checks `featured_image` field counts
     - Compares against previous counts
     - Alerts when fields are lost
   
   - **Audit Script**: `/v2/admin/produkt-updates/audit-featured-images.php`
     - Lists all features with missing `featured_image` fields
     - Shows unlinked images in library
     - Provides restore suggestions

6. **Health Check Extended**:

   `/v2/api/produkt-updates-storage-health.php` now includes:
   - Featured image field counts
   - Missing field detection
   - Image file validation
   - Migration status

**Recovery Procedure**:

If featured images are already unlinked:

1. **Check Current State**:
   ```
   GET /v2/admin/produkt-updates/audit-featured-images.php
   ```

2. **Recover from Backup**:
   ```
   GET /v2/admin/produkt-updates/recover-featured-images.php?action=analyze
   GET /v2/admin/produkt-updates/recover-featured-images.php?action=recover
   ```

3. **Monitor After Recovery**:
   ```
   GET /v2/admin/produkt-updates/monitor-featured-images.php
   ```

**Prevention**:

- Migration logic fixed to never overwrite existing fields
- Migration flag prevents re-migration on every page load
- Path resolution ensures consistency
- Save validation prevents data loss
- Comprehensive logging for debugging
- Monitoring tools detect issues immediately

**Related Files**:

- `v2/pages/produkt_updates_admin.php` - Migration logic (line ~1408-1500)
- `v2/includes/produkt-updates-paths.php` - Path resolution
- `v2/admin/produkt-updates/recover-featured-images.php` - Recovery script
- `v2/admin/produkt-updates/monitor-featured-images.php` - Monitoring script
- `v2/admin/produkt-updates/audit-featured-images.php` - Audit script

---

### Issue 2.5: Images Not Loading in Admin Panel Image Library

**Last Updated**: 2026-01-21

**Symptoms**:

- Admin panel shows "Failed to load images. Please try again." error
- Image library modal displays error message when opening "Select from Library" tab
- No images appear in the library grid (shows "No images found")
- Error occurs immediately when opening image manager
- Diagnostics endpoint returns 0 images even though images exist in directories

**Causes**:

1. **Stale Cache** (Most Common):
   - `listExistingImages()` uses a 5-minute file-based cache
   - Cache file: `sys_get_temp_dir() . '/produkt-updates-images-cache.json'`
   - If cache was created when directories were empty, it will show 0 images until cache expires
   - Cache persists even after images are uploaded

2. **Diagnostics Endpoint Errors**:
   - Diagnostics endpoint (`/v2/api/produkt-updates-diagnostics.php`) failing or returning invalid JSON
   - `existing_images` key missing from diagnostics response
   - Function redeclaration errors (fixed in 2026-01-21)

3. **Path Resolution Issues**:
   - Path resolution issues in `listExistingImages()` function
   - Directory scanning errors (permission issues, unreadable directories)
   - Incorrect path concatenation (fixed in 2026-01-21)

4. **Network/JSON Errors**:
   - Network errors preventing fetch request
   - Invalid JSON response from diagnostics endpoint
- JSON parsing errors in frontend

**Solutions**:

1. **Clear Image Discovery Cache** (First Step):

   The most common cause is a stale cache. Clear it manually:

   ```bash
   # Find cache file location
   php -r "echo sys_get_temp_dir() . '/produkt-updates-images-cache.json';"
   
   # Delete cache file
   rm /path/to/produkt-updates-images-cache.json
   
   # Or via PHP
   php -r "unlink(sys_get_temp_dir() . '/produkt-updates-images-cache.json');"
   ```

   After clearing cache, refresh the admin panel and open image library again.

2. **Check Diagnostics Endpoint**:

   ```
   GET /v2/api/produkt-updates-diagnostics.php?t=1234567890
   ```

   Verify response includes `existing_images` key with proper structure:
   ```json
   {
     "existing_images": {
       "wp-content/uploads/produkt-updates": {
         "path": "/path/to/dir",
         "exists": true,
         "count": 5,
         "images": [...]
       }
     }
   }
   ```

3. **Run Diagnostic Scripts**:

   ```
   GET /v2/admin/produkt-updates/debug-image-loading.php?password=debug2024
   GET /v2/admin/produkt-updates/scan-image-directories.php?password=debug2024
   GET /v2/admin/produkt-updates/test-image-api.php?password=debug2024
   ```

   These scripts will identify:
   - Which directories exist and are readable
   - How many images are found in each location
   - Whether diagnostics endpoint returns correct structure
   - Any path resolution mismatches

4. **Test Directory Scanning Directly**:

   ```bash
   # Test scanning function directly
   php -r "
   require_once 'v2/includes/produkt-updates-paths.php';
   require_once 'v2/api/produkt-updates-diagnostics.php';
   \$cache_file = sys_get_temp_dir() . '/produkt-updates-images-cache.json';
   if (file_exists(\$cache_file)) unlink(\$cache_file);
   \$result = listExistingImages();
   echo json_encode(\$result, JSON_PRETTY_PRINT);
   "
   ```

   This will show which directories are being scanned and how many images are found in each.

5. **Check Browser Console**:

   Open browser DevTools console and look for:
   - Network errors (404, 500, CORS)
   - JSON parsing errors
   - JavaScript errors in `loadImageLibrary()` function
   - Error messages from `adminDebugLog()`

6. **Verify Image Directories**:

   Check that image directories exist and are readable:
   ```bash
   ls -la wp-content/uploads/produkt-updates/
   ls -la v2/data/images/produkt-updates/
   ls -la v2/temp/produkt-updates/
   ```

7. **Check PHP Error Logs**:

   Look for errors related to:
   - `listExistingImages()` function
   - Directory scanning failures
   - Path resolution issues
   - File permission errors

6. **Common Fixes**:

   - **Path Resolution Issue**: Fixed in diagnostics endpoint - location keys now use proper relative paths
   - **Empty Directories**: System handles gracefully - shows "No images found" message
   - **Permission Errors**: Check directory permissions (should be 755 for directories, 644 for files)
   - **JSON Structure Mismatch**: Frontend now validates response structure before processing

**Recent Improvements** (2026-01-21):

- Enhanced `listExistingImages()` with improved path concatenation
- Added `discoverImagesFromJson()` to find images referenced in JSON data
- Improved error logging for directory scanning failures
- Fixed path key generation for consistent location identification
- Added debug logging for image discovery process

**Error Messages**:

- "Failed to load images. Please try again." - Generic error, check console for details
- "Server error while loading images" - HTTP error from diagnostics endpoint
- "Invalid response from server" - JSON parsing error
- "Network error" - Fetch request failed

**Prevention**:

- Enhanced error handling in `loadImageLibrary()` function
- Better error messages with retry button
- Structured logging for debugging
- Validation of response structure before processing
- Graceful handling of empty directories and permission errors

**Related Files**:

- `v2/pages/produkt_updates_admin.php` - `loadImageLibrary()` function (line ~12188)
- `v2/api/produkt-updates-diagnostics.php` - Diagnostics endpoint and `listExistingImages()` function
- `v2/admin/produkt-updates/debug-image-loading.php` - Diagnostic script
- `v2/admin/produkt-updates/scan-image-directories.php` - Directory scanner script

---

### Issue 3: Images Not Displaying on Public Pages

**Symptoms**:

- Images show broken/placeholder on public pages
- Image proxy returns 404 Not Found
- Images visible in admin panel but not on website

**Causes**:

- Images stored in `/tmp/` (lost on server restart)
- Path resolution mismatch (read vs write locations)
- Image proxy endpoint not finding images
- `findReadableImage()` not checking WordPress uploads directory

**Solutions**:

1. **Check Image Location**:

   ```
   GET /v2/admin/produkt-updates/list-images.php?password=...
   ```

   Verify images are in persistent location.

2. **Check Path Resolution**:

   ```
   GET /v2/admin/produkt-updates/analyze-production-setup.php?password=...
   ```

   Verify `findReadableImage()` includes WordPress uploads directory.

3. **Migrate Images** (if in `/tmp/`):

   ```
   GET /v2/admin/produkt-updates/migrate-missing-images.php?action=migrate&password=...
   ```

4. **Verify Image Proxy**:
   ```
   GET /v2/api/serve-produkt-updates-image.php?file=filename.webp
   ```
   Should return 200 OK with image data.

**Prevention**:

- Ensure images save to WordPress uploads directory
- Verify `findReadableImage()` checks all locations
- Monitor storage status regularly

---

### Issue 3: Admin Panel Shows Empty Data

**Symptoms**:

- Admin panel shows no months/features/improvements
- Dashboard shows "No months created yet"
- Public pages still show content

**Causes**:

- Data in `/tmp/` (lost on server restart)
- Admin panel reading from different location than public pages
- JSON file corrupted
- Path resolution mismatch

**Solutions**:

1. **Check Data File Location**:

   ```
   GET /v2/api/produkt-updates-storage-health.php
   ```

   Verify data file location and persistence.

2. **Check Path Resolution**:

   ```
   GET /v2/admin/produkt-updates/analyze-production-setup.php?password=...
   ```

   Verify admin and public pages use same location.

3. **Verify JSON File**:

   - Check if file exists
   - Verify file is readable
   - Check JSON validity

4. **Migrate Data** (if in `/tmp/`):
   ```
   GET /v2/admin/produkt-updates/migrate-to-persistent-storage.php?action=migrate&password=...
   ```

**Prevention**:

- Ensure data saves to persistent location
- Verify `findReadableDataFile()` checks writable location first
- Monitor storage status regularly

---

### Issue 3: Cannot Save Data in Admin Panel

**Symptoms**:

- "Error: Could not save data" message
- Changes not persisting
- Form submission fails

**Causes**:

- Data file not writable
- Directory not writable
- Disk space full
- Permission issues

**Solutions**:

1. **Check Storage Status**:

   ```
   GET /v2/api/produkt-updates-storage-health.php
   ```

   Verify data file is writable.

2. **Check Directory Permissions**:

   ```
   GET /v2/admin/produkt-updates/discover-writable-directories.php?password=...
   ```

   Find writable directories.

3. **Verify File Permissions**:

   - Check file owner (should be `www-data:www-data`)
   - Check file permissions (should be `644`)
   - Check directory permissions (should be `755`)

4. **Use WordPress Uploads Directory**:
   - System automatically uses WordPress uploads if available
   - No permission changes needed

**Prevention**:

- Use WordPress uploads directory (already writable)
- Monitor storage status
- Check disk space regularly

---

### Issue 4: Images Not Uploading

**Symptoms**:

- Upload fails with error message
- "Upload directory is not writable" error
- Images not appearing after upload

**Causes**:

- Image directory not writable
- PHP upload limits exceeded
- File size too large
- Invalid file type

**Solutions**:

1. **Check Image Directory**:

   ```
   GET /v2/api/produkt-updates-storage-health.php
   ```

   Verify image directory is writable.

2. **Check PHP Limits**:

   ```
   GET /v2/api/produkt-updates-diagnostics.php
   ```

   Check `upload_max_filesize` and `post_max_size`.

3. **Verify File**:

   - Check file size (< 5MB)
   - Check file type (JPEG, PNG, WebP, GIF)
   - Check dimensions (< 4000x4000px)

4. **Check Directory**:
   ```
   GET /v2/admin/produkt-updates/discover-writable-directories.php?password=...
   ```
   Find writable image directories.

**Prevention**:

- Use WordPress uploads directory
- Optimize images before upload
- Monitor upload limits

---

### Issue 5: Storage Status Shows Volatile Storage Warning

**Symptoms**:

- Admin panel shows "Using volatile storage" warning
- Storage Status card shows red/yellow indicators
- Warning about data loss on restart

**Causes**:

- Data/images stored in `/tmp/`
- Persistent directories not writable
- Path resolution falling back to `/tmp/`

**Solutions**:

1. **Discover Writable Directories**:

   ```
   GET /v2/admin/produkt-updates/discover-writable-directories.php?password=...
   ```

   Find persistent writable directories.

2. **Migrate to Persistent Storage**:

   ```
   GET /v2/admin/produkt-updates/migrate-to-persistent-storage.php?action=migrate&password=...
   GET /v2/admin/produkt-updates/migrate-missing-images.php?action=migrate&password=...
   ```

3. **Verify Migration**:
   ```
   GET /v2/api/produkt-updates-storage-health.php
   ```
   Should show persistent storage.

**Prevention**:

- Use WordPress uploads directory
- Monitor storage status regularly
- Fix permission issues proactively

---

### Issue 6: Admin Panel Shows Older Version

**Symptoms**:

- Missing features (Insights, Charts, Activity Trends)
- UI looks different from local
- Features not working

**Causes**:

- Code not deployed
- Browser cache
- Conditional rendering (no data)
- Version mismatch

**Solutions**:

1. **Check Version**:

   - Verify `ADMIN_VERSION` constant in code
   - Compare with production version

2. **Check Data**:

   - Verify data exists
   - Check if conditional rendering hiding features
   - Insights/Charts only show if data exists

3. **Clear Cache**:

   - Hard refresh browser (Ctrl+Shift+R)
   - Clear browser cache
   - Check CDN cache (if applicable)

4. **Verify Deployment**:
   - Check if files deployed correctly
   - Verify file modification dates
   - Test endpoints

**Prevention**:

- Use version constants for cache busting
- Test after deployment
- Monitor version numbers

---

### Issue 7: Path Resolution Mismatch

**Symptoms**:

- Admin panel and public pages show different data
- Changes in admin not visible on public pages
- Data inconsistency

**Causes**:

- Admin writes to different location than public reads from
- `findWritableDataFile()` and `findReadableDataFile()` using different locations
- Path resolution priority mismatch

**Solutions**:

1. **Check Locations**:

   ```
   GET /v2/api/produkt-updates-data-location-check.php
   ```

   Compare writable vs readable locations.

2. **Verify Path Resolution**:

   - Check `findWritableDataFile()` priority
   - Check `findReadableDataFile()` priority
   - Ensure `findReadableDataFile()` checks writable location first

3. **Fix Path Resolution**:
   - Update `produkt-updates-paths.php`
   - Ensure consistent priority order
   - Test on production

**Prevention**:

- Ensure `findReadableDataFile()` checks writable location first
- Test path resolution after changes
- Monitor storage status

---

### Issue 8: JSON File Corrupted

**Symptoms**:

- "Invalid JSON" errors
- Data not loading
- Admin panel shows errors

**Causes**:

- Partial write failure
- File corruption
- Invalid JSON structure
- Encoding issues

**Solutions**:

1. **Check JSON Validity**:

   ```
   GET /v2/api/produkt-updates-diagnostics.php
   ```

   Check `json_valid` field.

2. **Restore from Backup**:

   - Check `v2/data/backups/` directory
   - Restore most recent backup
   - Verify data integrity

3. **Fix JSON**:

   - Validate JSON structure
   - Fix syntax errors
   - Ensure UTF-8 encoding

4. **Prevent Future Issues**:
   - Use atomic writes (temp file + rename)
   - Create backups before bulk operations
   - Validate JSON before saving

**Prevention**:

- Always use atomic writes
- Create backups regularly
- Validate JSON structure
- Monitor error logs

---

### Issue 9: Image Proxy Returns 404

**Symptoms**:

- Images not loading
- 404 errors in browser console
- Image proxy endpoint returns "Image not found"

**Causes**:

- Image file doesn't exist
- `findReadableImage()` not checking correct location
- Filename mismatch
- Path resolution issue

**Solutions**:

1. **List Images**:

   ```
   GET /v2/admin/produkt-updates/list-images.php?password=...
   ```

   Compare referenced vs actual images.

2. **Check Path Resolution**:

   - Verify `findReadableImage()` includes WordPress uploads
   - Check all image directory locations
   - Test path resolution for specific image

3. **Migrate Images** (if missing):

   ```
   GET /v2/admin/produkt-updates/migrate-missing-images.php?action=migrate&password=...
   ```

4. **Verify Image File**:
   - Check if file exists on filesystem
   - Verify filename matches JSON reference
   - Check file permissions

**Prevention**:

- Ensure images save to persistent location
- Verify `findReadableImage()` checks all locations
- Monitor image references

---

### Issue 10: Session Expired / Cannot Login

**Symptoms**:

- "Session expired" message
- Cannot log in to admin panel
- Login form not accepting password

**Causes**:

- Session timeout (30 minutes)
- Invalid password
- Too many login attempts (lockout)
- Session storage issues

**Solutions**:

1. **Wait for Lockout** (if too many attempts):

   - Wait 15 minutes
   - Try logging in again

2. **Check Password**:

   - Verify password is correct
   - Check `admin_config.php` for password hash

3. **Clear Session**:

   - Clear browser cookies
   - Try incognito/private mode
   - Clear PHP session files (if accessible)

4. **Check Session Storage**:
   - Verify session directory is writable
   - Check PHP session configuration
   - Monitor session errors

**Prevention**:

- Use "Remember Me" for longer sessions
- Don't leave admin panel idle
- Monitor login attempts

## Diagnostic Tools Reference

### Quick Health Check

```
GET /v2/api/produkt-updates-storage-health.php
```

### Comprehensive Analysis

```
GET /v2/admin/produkt-updates/analyze-production-setup.php?password=...
```

### Image Analysis

```
GET /v2/admin/produkt-updates/list-images.php?password=...
```

### Full System Test

```
GET /v2/admin/produkt-updates/comprehensive-production-test.php?password=...
```

## Error Log Locations

### PHP Error Log

Standard PHP error_log() output. Check server configuration for location.

### Storage Log

`v2/logs/produkt-updates-storage.log`

Contains:

- Path resolution attempts
- Directory creation logs
- Storage operation errors
- Migration logs

### Admin Log

`v2/logs/produkt_updates_admin_YYYY-MM-DD.log`

Contains:

- Admin panel errors
- Form submission errors
- Data save errors
- User action logs

## Getting Help

### Self-Service Steps

1. Run diagnostic tools
2. Check error logs
3. Review this troubleshooting guide
4. Check related documentation

### When to Escalate

Escalate if:

- Diagnostic tools don't identify issue
- Data loss occurred
- System completely non-functional
- Security concerns

### Information to Provide

When reporting issues, include:

- Error messages
- Diagnostic tool output
- Error log excerpts
- Steps to reproduce
- Expected vs actual behavior

## Related Documentation

- [Diagnostic Tools](./PRODUCT_UPDATES_DIAGNOSTIC_TOOLS.md) - All diagnostic endpoints
- [Storage System](./PRODUCT_UPDATES_STORAGE.md) - Storage architecture
- [Development Guide](./PRODUCT_UPDATES_DEVELOPMENT_GUIDE.md) - Development procedures
