Skip to content

Instantly share code, notes, and snippets.

@davemac
Last active July 28, 2025 01:44
Show Gist options
  • Save davemac/e9d000e82f4d130ffa400a1efa75f59f to your computer and use it in GitHub Desktop.
Save davemac/e9d000e82f4d130ffa400a1efa75f59f to your computer and use it in GitHub Desktop.
WordPress test plugins to isolate errorrs
#!/bin/zsh
# WordPress Plugin Fatal Error Diagnostic Script
#
# Purpose: Systematically test individual plugins to isolate fatal error issues
# Setup: chmod +x plugin-memory.sh (make executable - only needed once)
# Usage: ./plugin-memory.sh (run from WordPress root directory)
#
# What it does:
# 1. Auto-detects site URL using wp-cli (wp option get home)
# 2. Auto-detects all currently active plugins using wp-cli
# 3. Tests each plugin individually by deactivating it
# 4. Clears debug log and makes a site request
# 5. Checks for fatal memory errors in wp-content/debug.log
# 6. Reactivates the plugin and moves to the next one
# 7. Saves detailed output to timestamped log file
#
# Key Features:
# - Fully automatic detection (site URL + active plugins)
# - Configurable skip list for critical plugins
# - macOS/zsh compatible (uses zsh array syntax)
# - Interactive mode - stops when culprit is found
# - Logging to both terminal and file
#
# Output: plugin_memory_test_YYYYMMDD_HHMMSS.txt with full test results
set -e # Exit on any error
# Create output file with timestamp
OUTPUT_FILE="plugin_memory_test_$(date +%Y%m%d_%H%M%S).txt"
# Function to output to both terminal and file
output() {
echo "$@" | tee -a "$OUTPUT_FILE"
}
# Configuration
LOG_FILE="wp-content/debug.log"
# Colours for output (only for terminal)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Colour
# Plugins to skip (add plugin names here that should never be tested)
# Example: critical security plugins, backup plugins, etc.
SKIP_PLUGINS="wordfence akismet updraftplus"
# Function to print coloured output
print_status() {
local colour=$1
local message=$2
echo -e "${colour}${message}${NC}" | tee -a "$OUTPUT_FILE"
}
# Initialize output file
echo "WordPress Plugin Memory Error Testing Script Output" > "$OUTPUT_FILE"
echo "Generated: $(date)" >> "$OUTPUT_FILE"
echo "========================================" >> "$OUTPUT_FILE"
# Check if we're in a WordPress directory
if [[ ! -f "wp-config.php" ]]; then
print_status $RED "Error: This script must be run from the WordPress root directory"
exit 1
fi
print_status $YELLOW "Starting WordPress plugin memory error testing..."
output "Output will be saved to: $OUTPUT_FILE"
# Check wp-cli availability first
if ! command -v wp &> /dev/null; then
print_status $RED "Error: wp-cli is not installed or not in PATH"
print_status $YELLOW "Please install wp-cli: https://wp-cli.org/"
exit 1
fi
# Auto-detect site URL using wp-cli
output "Detecting site URL..."
SITE_URL=$(wp option get home 2>/dev/null)
if [[ -z "$SITE_URL" ]]; then
print_status $RED "Error: Could not retrieve site URL"
print_status $YELLOW "Make sure wp-cli is working: wp option get home"
exit 1
fi
print_status $YELLOW "Site URL: $SITE_URL"
print_status $YELLOW "Log file: $LOG_FILE"
output ""
# Auto-detect active plugins using wp-cli
output "Detecting active plugins..."
# Get list of active plugins
PLUGINS=$(wp plugin list --status=active --field=name 2>/dev/null)
if [[ -z "$PLUGINS" ]]; then
print_status $RED "Error: Could not retrieve active plugins list"
print_status $YELLOW "Make sure wp-cli is working: wp plugin list"
exit 1
fi
# Convert to array and filter out skipped plugins
plugins_array=()
skip_array=(${=SKIP_PLUGINS})
# Convert newline-separated plugin list to array
while IFS= read -r plugin; do
[[ -n "$plugin" ]] || continue # Skip empty lines
# Check if plugin should be skipped
skip_plugin=false
for skip in "${skip_array[@]}"; do
if [[ "$plugin" == "$skip" ]]; then
output "⏭️ Skipping plugin: $plugin (in skip list)"
skip_plugin=true
break
fi
done
if [[ "$skip_plugin" == false ]]; then
plugins_array+=("$plugin")
fi
done <<< "$PLUGINS"
# Display detected plugins
output "Found ${#plugins_array[@]} active plugins to test:"
for plugin in "${plugins_array[@]}"; do
output " - $plugin"
done
output ""
# Explain what we're looking for
print_status $YELLOW "πŸ” What this script detects:"
output " β€’ Fatal memory errors: 'Allowed memory size of X bytes exhausted'"
output " β€’ PHP fatal errors: 'PHP Fatal error' messages"
output " β€’ Memory-related crashes that prevent site loading"
output ""
output "βœ… Success criteria: Site loads without fatal errors when plugin is deactivated"
output "❌ Problem identified: Fatal errors disappear when specific plugin is deactivated"
output ""
# Pre-check: Verify there's actually a fatal error to solve
print_status $YELLOW "πŸ”¬ Pre-check: Testing site with all plugins active..."
output "Clearing debug log..."
rm "$LOG_FILE" 2>/dev/null && touch "$LOG_FILE"
output "Making test request to site..."
if curl -s --max-time 10 --connect-timeout 5 --insecure "$SITE_URL" > /dev/null 2>&1; then
output "Site request successful"
# Wait for logs to be written
sleep 1
# Check for fatal errors
if ! grep -q "Fatal error" "$LOG_FILE" 2>/dev/null; then
print_status $GREEN "βœ… No fatal errors found!"
output ""
output "The site is currently working fine with all plugins active."
output "This script is designed to isolate plugins causing fatal errors."
output ""
print_status $YELLOW "Possible reasons:"
output " β€’ The issue has already been resolved"
output " β€’ The error only occurs under specific conditions"
output " β€’ The error is intermittent"
output " β€’ The error is theme-related, not plugin-related"
output ""
output "If you're still experiencing issues, try:"
output " β€’ Access different pages of your site"
output " β€’ Check wp-content/debug.log manually"
output " β€’ Use other diagnostic scripts in this directory"
output ""
output "Full output saved to: $OUTPUT_FILE"
exit 0
else
print_status $RED "❌ Fatal errors detected!"
output "Error details:"
grep "Fatal error" "$LOG_FILE" 2>/dev/null | head -3 | while read -r error_line; do
output " $error_line"
done
output ""
print_status $YELLOW "Proceeding with plugin isolation testing..."
output ""
fi
else
print_status $RED "⚠️ Could not reach site - proceeding with testing anyway"
output "This might indicate a severe error that prevents site loading"
output ""
fi
for plugin in "${plugins_array[@]}"; do
output "Testing plugin: $plugin"
# Deactivate plugin (removed timeout - this was causing the hangs)
output " β†’ Deactivating plugin..."
if wp plugin deactivate "$plugin" --quiet 2>/dev/null; then
output " β†’ Plugin deactivated successfully"
# Clear log file (using method that works on macOS)
output " β†’ Clearing log file..."
rm "$LOG_FILE" 2>/dev/null && touch "$LOG_FILE"
output " β†’ Log file cleared successfully"
# Wait a moment for any pending operations
output " β†’ Waiting 2 seconds for changes to take effect..."
sleep 2
output " β†’ Wait complete"
# Make request to site
output " β†’ Making request to site ($SITE_URL)..."
output " β†’ Running: curl -s --max-time 10 --connect-timeout 5 --insecure $SITE_URL"
if curl -s --max-time 10 --connect-timeout 5 --insecure "$SITE_URL" > /dev/null 2>&1; then
output " β†’ Site request successful"
# Wait a moment for logs to be written
sleep 1
# Check for fatal errors in log
output " β†’ Checking log file for fatal errors..."
output " β†’ Searching for pattern: 'Fatal error' in $LOG_FILE"
if ! grep -q "Fatal error" "$LOG_FILE" 2>/dev/null; then
print_status $GREEN "βœ… Fatal error GONE when $plugin is deactivated. This is the culprit!"
# Ask if user wants to stop here
print_status $YELLOW "Found the problematic plugin: $plugin"
echo "Would you like to stop testing here? (y/n): "
read -r response
output "User response: $response"
if [[ "$response" =~ ^[Yy]$ ]]; then
print_status $YELLOW "Testing stopped at user request"
output "Plugin causing issues: $plugin"
# Reactivate the plugin before exiting
output "Reactivating problematic plugin..."
wp plugin activate "$plugin" --quiet 2>/dev/null
output "Full output saved to: $OUTPUT_FILE"
exit 0
fi
else
print_status $RED "❌ Fatal error still present with $plugin deactivated"
output " β†’ Error details:"
grep "Fatal error" "$LOG_FILE" 2>/dev/null | head -2 | while read -r error_line; do
output " $error_line"
done
fi
else
print_status $YELLOW "⚠️ Could not reach site or request failed"
fi
# Reactivate plugin (removed timeout)
output " β†’ Reactivating plugin..."
if wp plugin activate "$plugin" --quiet 2>/dev/null; then
output " β†’ Plugin reactivated successfully"
else
print_status $RED "Warning: Could not reactivate plugin '$plugin'"
fi
else
print_status $RED "Error: Could not deactivate plugin '$plugin'"
fi
output "---------------------------------"
done
print_status $YELLOW "Testing complete!"
output "Full output saved to: $OUTPUT_FILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment