What's Actually Happening

You ran drush up or updated Drupal modules through the admin interface, but something went wrong. Now your Drupal site is broken: pages show error messages, some features don't work, or the entire site is inaccessible. The update process either failed mid-way, applied updates incorrectly, or created database schema mismatches between the module code and the database.

This commonly happens when: a module's update hook encounters an error and stops execution; dependencies between modules cause conflicts during simultaneous updates; the database migration ran partially and now your database schema is in an inconsistent state; or the updated module code has bugs that weren't caught during testing.

The Error You'll See

Drupal module update failures manifest in various ways depending on where the failure occurred:

```bash # When running drush up command $ drush up

Update manager started. Preparing to update the following modules: - views (7.x-3.21 -> 7.x-3.23) - node (8.x-2.1 -> 8.x-2.3)

[error] Update failed: views_update_8300() - SQL error: Duplicate column name 'views_display_options'

[error] An AJAX HTTP error occurred. HTTP Result Code: 500 Path: /update.php?id=23&op=do StatusText: Service unavailable (with message) ResponseText: Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S21]: Column already exists

# In Drupal logs (admin/reports/dblog) Type: php Message: Warning: Attempted to execute update hook views_update_8301 but views_update_8300 failed Severity: error

Type: system Message: Failed to run update function node_update_8203 in node.module Severity: critical

# When accessing the site after failed update HTTP 500 Internal Server Error The website encountered an unexpected error. Please try again later.

# In browser when logged in as admin Error message: The following updates are pending: - views module: 8300, 8301, 8302 Run update.php to finalize.

# On specific pages Error: Call to undefined method Drupal\views\ViewEntity::getDisplayOptions() in Drupal\views\Plugin\views\display\DefaultDisplay->execute()

# Database exception when accessing content Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'node.field_example_value'

# Drush status showing pending updates $ drush updb --status [status] 3 pending updates for views module [status] 2 pending updates for node module [warning] Update process incomplete - database schema mismatch detected ```

Additional symptoms: - White screen of death (WSOD) on specific pages - Missing functionality that depends on updated modules - Error messages about missing database tables or columns - drush commands failing with database exceptions - Admin interface inaccessible or partially broken - Update.php page showing pending updates that won't run

Why This Happens

  1. 1.Partial Update Execution: The update hook started but stopped midway due to an error. One update hook (like views_update_8300) completed partially, leaving the database schema in a state that prevents subsequent hooks from running. Drupal's update system requires each numbered hook to complete successfully before running the next one.
  2. 2.Database Transaction Failure: Some update hooks use database transactions that didn't commit properly due to timeouts, deadlocks, or connection issues. The transaction rolled back partially, leaving the schema inconsistent. MySQL's default timeout of 50 seconds can kill long-running update operations.
  3. 3.Module Dependency Order Issues: You updated multiple modules simultaneously, but they have dependencies that require a specific order. Module A depends on Module B's new schema, but Module A's update ran first because Drupal's update.php doesn't enforce dependency ordering between modules.
  4. 4.Schema Collision with Custom Code: Your custom modules or contrib modules modified the same database tables. When core or a contrib module tries to add a column that your custom code already added, the update fails with a "duplicate column" error.
  5. 5.Insufficient Database Privileges: The database user lacks permissions to alter tables, create indexes, or modify schema. The update hook tries to run ALTER TABLE commands that require ALTER, CREATE, or INDEX privileges that the Drupal database user doesn't have.
  6. 6.Memory or Timeout Limits: PHP ran out of memory during a complex update hook, or the request timed out before completion. Large updates that modify millions of rows or create complex indexes can exceed PHP's memory_limit or max_execution_time.
  7. 7.Corrupted Update Registry: Drupal's update registry (the key_value table with system.schema collection) has incorrect values. It shows that an update was applied when it wasn't, or vice versa, causing Drupal to skip needed updates or try to re-run completed ones.
  8. 8.Module Code Bugs: The new module version has a bug in its update hook code. The update function references columns that don't exist yet, calls methods that changed, or has logic errors that cause it to fail.

Step 1: Assess the Damage and Identify Failed Updates

First, determine which updates failed and what state your database is in.

```bash # SSH into your server ssh user@your-drupal-server

# Navigate to Drupal directory cd /var/www/your-drupal-site

# Check Drupal core status drush status

# Check for pending updates drush updb --status

# If drush doesn't work, check via update.php # Visit: https://your-site.com/update.php # You'll need to set $settings['update_free_access'] = TRUE; temporarily

# Check the update registry directly drush sql:query "SELECT name, value FROM key_value WHERE collection = 'system.schema'"

# If drush sql-cli works: drush sql:cli

# In MySQL console, run: SELECT name, value FROM key_value WHERE collection = 'system.schema';

# Look at the schema versions - compare to module .install files # Example output: # name: views, value: 8200 (but update hooks go up to 8303) # This means views needs updates 8300, 8301, 8302, 8303

# Check recent watchdog logs drush watchdog:show --type=php --severity=error --limit=20

# Check database errors specifically drush watchdog:show --type=system --severity=critical --limit=20

# Look for specific update hook failures grep -r "update_" modules/contrib/views/views.install | head -20

# Check what the failed update was trying to do cat modules/contrib/views/views.install

# Check PHP error logs tail -100 /var/log/php-fpm/error.log tail -100 /var/log/apache2/error.log tail -100 /var/log/nginx/error.log

# Check if the site is completely down curl -I https://your-site.com/ ```

Document which modules have pending updates and what the last successful update hook number was for each.

Step 2: Backup Database Before Recovery

Before attempting any recovery, create a complete backup of your current database state. This allows you to try different recovery approaches without losing data.

```bash # Create backup directory mkdir -p /tmp/drupal-backup-$(date +%Y%m%d-%H%M%S) BACKUP_DIR=/tmp/drupal-backup-$(date +%Y%m%d-%H%M%S)

# Backup database drush sql:dump --result-file="$BACKUP_DIR/database.sql"

# Or use mysqldump directly if drush doesn't work: mysqldump -u drupal_user -p drupal_database > "$BACKUP_DIR/database.sql"

# Backup the codebase tar -czf "$BACKUP_DIR/code.tar.gz" modules/ themes/ sites/

# Backup Drupal files directory tar -czf "$BACKUP_DIR/files.tar.gz" sites/default/files/

# Backup configuration (for Drupal 8+) tar -czf "$BACKUP_DIR/config.tar.gz" config/

# Record current schema state drush sql:query "SELECT name, value FROM key_value WHERE collection = 'system.schema'" > "$BACKUP_DIR/schema-state.txt"

# Check database size du -sh "$BACKUP_DIR/"

# Verify backup was created successfully ls -lh "$BACKUP_DIR/" ```

Store these backups somewhere safe - they represent your site's state at the moment of failure, which you may need for forensic analysis.

Step 3: Examine Failed Update Hook Code

Look at the specific update hook that failed to understand what it was trying to do and where it stopped.

```bash # Find the module's .install file cat modules/contrib/views/views.install

# Or for a contributed module: cat modules/contrib/YOUR_MODULE/YOUR_MODULE.install

# Search for the specific failing update function grep -A 50 "function views_update_8300" modules/contrib/views/views.install

# Example of a typical update hook: function views_update_8300(&$sandbox = NULL) { // Add a new column to views_display table $spec = [ 'description' => 'Display options for the view.', 'type' => 'text', 'size' => 'big', 'not null' => FALSE, ]; \Drupal::database()->schema()->addField('views_display', 'views_display_options', $spec);

// Update existing records if (!isset($sandbox['progress'])) { $sandbox['progress'] = 0; $sandbox['total'] = \Drupal::database()->query('SELECT COUNT(*) FROM {views_display}')->fetchField(); $sandbox['current'] = 0; }

// Process in batches $views = \Drupal::database()->queryRange('SELECT * FROM {views_display}', $sandbox['current'], 50); foreach ($views as $view) { // Update logic here $sandbox['current']++; $sandbox['progress'] = $sandbox['current'] / $sandbox['total']; }

// Tell Drupal if we're done $sandbox['#finished'] = $sandbox['progress']; if ($sandbox['#finished'] >= 1) { return 'Added views_display_options column to all views.'; } }

# Check if the table modification was partially applied drush sql:query "DESCRIBE views_display"

# Compare to what the update expects # If the column 'views_display_options' exists but update says it failed, # the column was added but the batch processing didn't complete

# Check the batch table for pending batch operations drush sql:query "SELECT * FROM batch WHERE token LIKE '%update%'"

# Check if there are leftover sandbox data drush sql:query "SELECT * FROM key_value WHERE collection LIKE '%update.sandbox%'" ```

Understanding what the update hook does helps you determine if you can manually complete it or need to roll back.

Step 4: Manually Complete or Skip Failed Updates

Based on your analysis, either complete the update manually or tell Drupal to skip it.

```bash # Option A: Manually complete the partial update # If the update hook added a column but didn't finish batch processing:

drush sql:cli

# Check current state SELECT * FROM views_display LIMIT 10;

# If the column exists but data wasn't populated, populate it manually: UPDATE views_display SET views_display_options = '{}' WHERE views_display_options IS NULL;

# Or for more complex updates, write a custom script: php scripts/complete-views-update.php

# Option B: Skip a failed update if it's not critical # Tell Drupal the update was applied even though it failed:

drush sql:cli

# Update the schema registry to mark the hook as complete # For views module, if 8300 failed but we want to skip it: UPDATE key_value SET value = '8300' WHERE collection = 'system.schema' AND name = 'views';

# Or use drush: drush ev "\Drupal::keyValue('system.schema')->set('views', 8300);"

# Option C: Roll back the partial update # If the update added a column that's causing problems:

drush sql:cli

# Remove the partially-added column ALTER TABLE views_display DROP COLUMN views_display_options;

# Reset the schema version to before the failed update UPDATE key_value SET value = '8299' WHERE collection = 'system.schema' AND name = 'views';

# Option D: Run the update hook manually with fixes # Create a custom script to run the update logic

nano scripts/manual-update-views.php ```

```php <?php // Manual update script for views module // Run with: drush scr scripts/manual-update-views.php

use Drupal\Core\Database\Database;

$connection = Database::getConnection();

// Check if column already exists if (!$connection->schema()->fieldExists('views_display', 'views_display_options')) { $spec = [ 'description' => 'Display options for the view.', 'type' => 'text', 'size' => 'big', 'not null' => FALSE, ]; $connection->schema()->addField('views_display', 'views_display_options', $spec); echo "Added views_display_options column\n"; } else { echo "Column already exists\n"; }

// Update existing records with default value $count = $connection->update('views_display') ->fields(['views_display_options' => '{}']) ->condition('views_display_options', NULL, 'IS NULL') ->execute();

echo "Updated $count records\n";

// Mark update as complete \Drupal::keyValue('system.schema')->set('views', 8300); echo "Marked views_update_8300 as complete\n"; ```

```bash # Run the manual update script drush scr scripts/manual-update-views.php

# Verify the update was marked complete drush sql:query "SELECT value FROM key_value WHERE collection = 'system.schema' AND name = 'views'" ```

Step 5: Fix Database Schema Mismatch

Resolve any schema mismatches between what Drupal expects and what's in your database.

```bash # Compare expected schema to actual schema # For each affected table:

drush sql:query "DESCRIBE views_display"

# Compare this to the schema defined in the module: grep -A 100 "'views_display'" modules/contrib/views/views.install

# Use Drupal's schema inspection to compare: drush ev " \$schema = \Drupal::database()->schema(); \$fields = \$schema->getFieldNames('views_display'); print_r(\$fields); "

# Find missing columns drush ev " \$module_handler = \Drupal::moduleHandler(); \$schema = \Drupal::database()->schema(); \$expected = \$module_handler->invoke('views', 'schema'); \$actual_fields = \$schema->getFieldNames('views_display'); \$expected_fields = array_keys(\$expected['views_display']['fields']); \$missing = array_diff(\$expected_fields, \$actual_fields); echo 'Missing columns: ' . implode(', ', \$missing); "

# Find extra columns that shouldn't exist drush ev " \$module_handler = \Drupal::moduleHandler(); \$schema = \Drupal::database()->schema(); \$expected = \$module_handler->invoke('views', 'schema'); \$actual_fields = \$schema->getFieldNames('views_display'); \$expected_fields = array_keys(\$expected['views_display']['fields'] ?? []); \$extra = array_diff(\$actual_fields, \$expected_fields); echo 'Extra columns: ' . implode(', ', \$extra); "

# Add missing columns manually drush sql:cli

ALTER TABLE views_display ADD COLUMN views_display_options TEXT;

# Or use Drupal's schema API: drush ev " \$spec = [ 'type' => 'text', 'size' => 'big', 'not null' => FALSE, ]; \Drupal::database()->schema()->addField('views_display', 'views_display_options', \$spec); "

# Remove extra columns if they're causing problems ALTER TABLE views_display DROP COLUMN old_column_name;

# Fix incorrect column types ALTER TABLE views_display MODIFY views_display_options LONGTEXT;

# Add missing indexes ALTER TABLE views_display ADD INDEX idx_views_display_options (views_display_options(255));

# Fix primary key issues ALTER TABLE views_display DROP PRIMARY KEY, ADD PRIMARY KEY (id, display_id); ```

Step 6: Clear All Drupal Caches

After fixing the schema, clear all caches to ensure Drupal uses fresh metadata.

```bash # Clear all caches using drush drush cache:rebuild

# Or clear specific caches drush cache:clear bootstrap drush cache:clear css-js drush cache:clear render drush cache:clear page drush cache:clear data drush cache:clear discovery

# Clear entity cache drush ev "\Drupal::entityManager()->clearCachedDefinitions();"

# Clear module hook cache drush ev "\Drupal::moduleHandler()->resetImplementations();"

# Clear theme registry drush ev "\Drupal::theme()->resetActiveTheme();"

# Clear router cache drush router:rebuild

# If drush doesn't work, clear caches manually: rm -rf sites/default/files/php/*

# For Drupal 8/9/10: rm -rf sites/default/files/php/twig/* rm -rf sites/default/files/php/service_definitions/* rm -rf sites/default/files/css/* rm -rf sites/default/files/js/*

# For Drupal 7: rm -rf sites/default/files/cache/* drush sql:query "DELETE FROM cache" drush sql:query "DELETE FROM cache_bootstrap" drush sql:query "DELETE FROM cache_block" drush sql:query "DELETE FROM cache_field" drush sql:query "DELETE FROM cache_filter" drush sql:query "DELETE FROM cache_form" drush sql:query "DELETE FROM cache_image" drush sql:query "DELETE FROM cache_menu" drush sql:query "DELETE FROM cache_page" drush sql:query "DELETE FROM cache_path" drush sql:query "DELETE FROM cache_update" drush sql:query "DELETE FROM cache_views" drush sql:query "DELETE FROM cache_views_data"

# Clear APC/APCu cache if used drush ev "if (function_exists('apcu_clear_cache')) apcu_clear_cache();"

# Clear Memcached if used drush ev "if (class_exists('Memcached')) { \$m = new Memcached(); \$m->flush(); }"

# Clear Redis if used redis-cli FLUSHDB ```

Step 7: Re-run Pending Updates

Now attempt to run the remaining updates after fixing the schema issues.

```bash # Run pending database updates drush updb

# Run with verbose output to see each hook execution drush updb -v

# Run specific module updates only drush updb --module=views

# Force re-run of a specific update number (if needed) drush ev " \$schema = \Drupal::keyValue('system.schema'); \$current = \$schema->get('views'); // Reset to force re-run of specific update \$schema->set('views', 8299); "

# Then run updates again drush updb

# Check if there are still pending updates drush updb --status

# If updates still fail, run via update.php # Enable update.php access temporarily: nano sites/default/settings.php ```

Add or uncomment: ``php $settings['update_free_access'] = TRUE;

```bash # Visit: https://your-site.com/update.php # Run updates through the web interface

# Disable update.php access after completion nano sites/default/settings.php ```

Remove the line: ``php // $settings['update_free_access'] = TRUE;

Step 8: Verify Module Functionality

Test that the affected modules are working correctly after the recovery.

```bash # Check module status drush pm:list --type=module --status=enabled

# Check for module-specific errors drush watchdog:show --type=views --limit=20

# Test module pages curl -I https://your-site.com/admin/structure/views

# Test views listing drush views:list

# Test specific view drush views:execute your_view_name

# Check for PHP errors drush watchdog:show --type=php --severity=error --limit=10

# Run module-specific validation if available # For views module: drush views:analyze

# Check configuration drush config:export --destination=/tmp/config-export cat /tmp/config-export/views.view.*.yml | grep -i "display_options"

# Verify database tables are correct drush sql:query "SELECT * FROM views_display LIMIT 5"

# Check field storage if the module added fields drush field:info

# Test content creation drush node:create --type=article --title="Test Article"

# Verify node displays correctly drush node:view 1

# Check if all dependencies are satisfied drush pm:info views

# Test features that depend on the updated module # For example, test node listing if views module was updated: curl -s https://your-site.com/node | grep -v "error|exception" ```

Step 9: Update Deployment Process to Prevent Recurrence

Modify your module update process to avoid failures in the future.

bash
# Create a safe update script
nano scripts/safe-drupal-update.sh

```bash #!/bin/bash set -e

# Safe Drupal Module Update Script DRUSH="drush" BACKUP_DIR="/tmp/drupal-update-backup-$(date +%Y%m%d-%H%M%S)"

echo "=== Starting Safe Drupal Update Process ==="

# 1. Backup database echo "Backing up database..." mkdir -p "$BACKUP_DIR" $DRUSH sql:dump --result-file="$BACKUP_DIR/database.sql"

# 2. Backup code echo "Backing up codebase..." tar -czf "$BACKUP_DIR/modules.tar.gz" modules/ tar -czf "$BACKUP_DIR/themes.tar.gz" themes/

# 3. Check current status echo "Current status:" $DRUSH status $DRUSH updb --status

# 4. Update modules one at a time (more reliable) # Get list of modules with pending updates PENDING=$(drush updb --status | grep "pending updates" | awk '{print $2}')

for MODULE in $PENDING; do echo "Updating $MODULE..."

# Get current schema version CURRENT_SCHEMA=$($DRUSH sql:query "SELECT value FROM key_value WHERE collection = 'system.schema' AND name = '$MODULE'" | tail -1) echo "Current schema: $CURRENT_SCHEMA"

# Run updates for this module only $DRUSH updb --module=$MODULE -v || { echo "Update failed for $MODULE" echo "Check logs and retry manually"

# Don't continue with other modules if one fails break }

# Clear caches after each module update $DRUSH cache:rebuild

echo "$MODULE updated successfully" done

# 5. Final cache clear echo "Clearing all caches..." $DRUSH cache:rebuild

# 6. Verify updates completed echo "Verifying updates..." $DRUSH updb --status

# 7. Check for errors echo "Checking for errors..." $DRUSH watchdog:show --severity=error --limit=10

echo "=== Update Process Complete ===" ```

```bash # Make script executable chmod +x scripts/safe-drupal-update.sh

# Update settings to increase PHP limits during updates nano sites/default/settings.php ```

Add: ``php // Increase limits for update operations if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE === 'update') { ini_set('memory_limit', '512M'); ini_set('max_execution_time', 300); }

bash
# Create a maintenance mode script for updates
nano scripts/enable-maintenance.sh
bash
#!/bin/bash
drush state:set system.maintenance_mode 1 --input-format=integer
drush cache:rebuild
echo "Site in maintenance mode"
bash
nano scripts/disable-maintenance.sh
bash
#!/bin/bash
drush state:set system.maintenance_mode 0 --input-format=integer
drush cache:rebuild
echo "Site back online"

Step 10: Set Up Pre-Update Testing and Monitoring

Create checks to validate module updates before applying them to production.

bash
# Create a pre-update check script
nano scripts/pre-update-check.sh

```bash #!/bin/bash # Pre-Update Validation Script

echo "=== Pre-Update Validation ==="

# Check database connection drush sql:connect || { echo "ERROR: Cannot connect to database"; exit 1; }

# Check database size DB_SIZE=$(drush sql:query "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) FROM information_schema.tables WHERE table_schema = DATABASE()" | tail -1) echo "Database size: $DB_SIZE MB"

# Check for pending updates PENDING=$(drush updb --status) if echo "$PENDING" | grep -q "pending"; then echo "WARNING: There are already pending updates!" echo "$PENDING" fi

# Check disk space DISK_USAGE=$(df -h /var/www | tail -1 | awk '{print $5}' | sed 's/%//') if [ "$DISK_USAGE" -gt 80 ]; then echo "WARNING: Disk usage at ${DISK_USAGE}%" fi

# Check PHP memory limit PHP_MEM=$(drush ev "echo ini_get('memory_limit');") echo "PHP memory limit: $PHP_MEM"

# Check modules status drush pm:list --type=module --status=enabled --no-core

# Check recent errors ERRORS=$(drush watchdog:show --severity=error --limit=5) if [ -n "$ERRORS" ]; then echo "WARNING: Recent errors found:" echo "$ERRORS" fi

# Check database privileges drush sql:query "SHOW GRANTS FOR CURRENT_USER();"

# Verify backup capability drush sql:dump --result-file=/tmp/test-backup.sql && rm /tmp/test-backup.sql echo "Backup capability: OK"

echo "=== Pre-Update Validation Complete ===" ```

bash
# Add monitoring for update failures
nano scripts/monitor-drupal-updates.sh

```bash #!/bin/bash # Monitor for pending/failed updates

LOG_FILE="/var/log/drupal-update-monitor.log" ALERT_EMAIL="ops@your-company.com"

# Check for pending updates PENDING=$(drush updb --status 2>&1) if echo "$PENDING" | grep -q "pending"; then COUNT=$(echo "$PENDING" | grep -c "pending") echo "$(date): $COUNT modules have pending updates" >> "$LOG_FILE"

if [ "$COUNT" -gt 5 ]; then echo "ALERT: $COUNT modules have pending updates on production" | mail -s "Drupal Update Alert" "$ALERT_EMAIL" fi fi

# Check for recent update errors in logs ERRORS=$(drush watchdog:show --type=system --severity=critical --since="1 hour ago" 2>&1) if echo "$ERRORS" | grep -qi "update.*failed|schema.*mismatch"; then echo "$(date): Update errors detected" >> "$LOG_FILE" echo "$ERRORS" | mail -s "Drupal Update Error Alert" "$ALERT_EMAIL" fi

# Check database schema consistency SCHEMA_ERRORS=$(drush ev " \$modules = ['views', 'node', 'user', 'taxonomy', 'field']; \$errors = []; foreach (\$modules as \$module) { if (!\Drupal::moduleHandler()->moduleExists(\$module)) continue; \$schema = \Drupal::database()->schema(); \$expected = \Drupal::moduleHandler()->invoke(\$module, 'schema') ?: []; foreach (\$expected as \$table => \$definition) { if (!\$schema->tableExists(\$table)) { \$errors[] = \"Table \$table missing for \$module\"; } } } echo implode('\\n', \$errors); ")

if [ -n "$SCHEMA_ERRORS" ]; then echo "$(date): Schema errors detected: $SCHEMA_ERRORS" >> "$LOG_FILE" echo "Schema errors:\n$SCHEMA_ERRORS" | mail -s "Drupal Schema Alert" "$ALERT_EMAIL" fi

echo "$(date): Check complete - no critical issues" >> "$LOG_FILE" ```

bash
# Add to cron
crontab -e
# Add:
*/30 * * * * /var/www/your-drupal-site/scripts/monitor-drupal-updates.sh

Checklist for Recovering from Drupal Module Update Failure

StepActionCommandStatus
1Assess damage and identify failed updatesdrush updb --status
2Backup database before recoverydrush sql:dump > backup.sql
3Examine failed update hook codegrep "function module_update_N" module.install
4Manually complete or skip failed updatesUpdate schema registry or run hook manually
5Fix database schema mismatchesAdd/remove columns manually
6Clear all Drupal cachesdrush cache:rebuild
7Re-run pending updatesdrush updb -v
8Verify module functionalityTest affected module pages
9Update deployment processCreate safe update script
10Set up pre-update testing and monitoringCreate validation scripts and cron jobs

Verify the Fix

After recovery, verify your Drupal site is fully functional:

```bash # 1. Check no pending updates remain drush updb --status # Should show "No pending updates"

# 2. Verify site is accessible curl -I https://your-site.com/ # Should return HTTP 200

# 3. Check watchdog for no recent errors drush watchdog:show --severity=error --since="1 hour ago" # Should return empty or only pre-existing errors

# 4. Verify module status drush pm:list --type=module --status=enabled # All modules should show correct version

# 5. Test specific functionality # For views module: drush views:list drush views:execute default_content

# 6. Verify database schema drush sql:query "DESCRIBE views_display" # Columns should match expected schema

# 7. Check configuration export drush config:export --destination=/tmp/verify-config # Should export successfully

# 8. Test content operations drush node:create --type=page --title="Update Recovery Test" drush node:view -- nid=$(drush sql:query "SELECT MAX(nid) FROM node" | tail -1)

# 9. Run cron to verify everything works drush cron

# 10. Verify cache rebuild works drush cache:rebuild # Should complete without errors ```

  • [Fix Symfony Cache Corrupted](/articles/fix-symfony-cache-corrupted) - Symfony-specific cache issues
  • [Fix Laravel Migration Locked](/articles/fix-laravel-migration-locked) - Laravel database migration issues
  • [Fix WordPress PHP Version Incompatible](/articles/fix-wordpress-php-version-incompatible) - WordPress PHP compatibility
  • [Fix PHP Composer Dependency Conflict](/articles/fix-php-composer-dependency-conflict) - Composer dependency resolution
  • [Fix PHP-FPM Pool Exhausted](/articles/fix-php-fpm-pool-exhausted) - PHP-FPM worker pool issues
  • [Fix Site Down After PHP Update](/articles/fix-site-down-after-php-update) - Post-PHP-update recovery
  • [Fix Database Migration Conflict](/articles/fix-django-database-migration-conflict) - Django migration issues