Skip to main content
GrN.dk

Main navigation

  • Articles
  • Contact
  • Your Digital Project Manager
  • About Greg Nowak
  • Services
  • Portfolio
  • Container
    • Excel Freelancer
    • Kubuntu - tips and tricks
    • Linux Apache MySQL and PHP
    • News
    • Image Gallery
User account menu
  • Log in

Breadcrumb

  1. Home

How to Fix Drush Symfony PHP Errors in Drupal

If you are seeing a fatal error around EventDispatcher::dispatch() when running Drush, treat it as a toolchain problem first, not a content problem. The usual failure is simple: the Drush binary being executed was installed in one place, while the Drupal site is loading Symfony components from another. That mismatch is common on inherited servers, shared agency boxes, and developer machines with old global Composer installs. For a business owner or operations lead, the real issue is not the stack trace. It is that routine maintenance, deployments, or recovery commands can stop working at exactly the wrong time.

The good news is that the fix is usually straightforward. The outdated habit was to keep adding Symfony packages to Composer global until the error disappeared. That can temporarily silence one site and break the next. The current safe model is to install Drush inside each Drupal project, run that copy, and let the site’s composer.lock define the dependency set.

What this error usually means

The classic symptom is a fatal error mentioning Symfony\Component\EventDispatcher\EventDispatcher::dispatch(). This started showing up when Symfony changed the dispatch() signature and older tooling expected a different call pattern. If your stack trace mixes a global Drush path such as /usr/local/drush or a Composer home directory with the site’s own /vendor/symfony/..., you are effectively cross-wiring two dependency trees.

That is why one Drupal site can work while another fails on the same server. It is also why quick fixes in a shared global Composer directory age badly. Global Composer state is shared per user account, so one emergency change can quietly alter the CLI environment for every other project that user touches.

The safest fix for a live Drupal project

Install Drush as a project dependency and run the project binary from the site root. That keeps Drush aligned with the Drupal, PHP, and Symfony versions the site is actually using.

composer require drush/drush
vendor/bin/drush status
vendor/bin/drush version

If your team prefers a shorter command, use Composer’s vendored-binary execution support or add ./vendor/bin to the shell path only in the project context. The important part is not the command length. It is that automation, deploy hooks, cron jobs, and emergency runbooks stop depending on whatever happens to live in /usr/local/bin or Composer global.

If the site is older, do not blindly pull the newest Drush major. Match the project to a compatible Drush version inside the repository instead of relying on a global install. As of June 11, 2026, the current Drush compatibility table lists Drush 13 as supported for Drupal 10.2+ and Drush 14 as supported for Drupal 11.3+.

For production teams, make the change complete: commit the updated composer.json and composer.lock, update deployment scripts to call the repo-local binary, and remove undocumented server-level Drush shortcuts. Partial fixes are how the same outage returns three months later during a rushed release window.

How to diagnose the mismatch before you touch versions

If the site is old or the stack has been inherited, check where Drush is coming from and what is blocking a clean upgrade path before you pin anything.

which drush
vendor/bin/drush version
composer config --global home
composer why symfony/event-dispatcher
composer prohibits drush/drush ^13
composer check-platform-reqs

These commands answer different questions. which drush shows whether your shell is resolving a global binary. vendor/bin/drush version confirms the project copy. composer config --global home shows the shared Composer home that may be affecting your workflow. composer why and composer prohibits show what currently requires or blocks the package versions you want. composer check-platform-reqs helps you separate a dependency problem from a PHP runtime problem.

If you are targeting a different Drush major, change the version constraint in the prohibits command. The point is to inspect the blocker chain first, not to guess at package pins until Composer stops complaining.

If you are stuck on legacy Drupal for now

Sometimes a clean upgrade is not immediately possible. A site may be tied to an older Drupal major, a hosting image you do not control, or a release process nobody wants to touch mid-campaign. In that situation, the practical goal is containment.

Containment means matching a compatible Drush major inside the project, documenting that choice, and treating it as transitional. Current Drush guidance is explicit: older Drush lines may still be compatible with some legacy Drupal versions, but they are no longer supported. That distinction matters. Compatible may get tonight’s deployment out the door; it does not make the stack low-risk.

What you should avoid is rebuilding the old global workaround by hand with commands like composer global require symfony/event-dispatcher ... one package at a time. That approach can leave one server able to run one site’s commands while breaking another site on the same account. If a global workaround is unavoidable for a short period, isolate it, document it, and plan its removal.

What to standardise across teams

  • Keep Drush inside each Drupal repository rather than in a shared global toolchain.
  • Call vendor/bin/drush in CI, deploy scripts, cron, and incident runbooks.
  • Check Drupal, PHP, and Drush compatibility before upgrades, not after a fatal error.
  • Use Composer diagnostics to understand blockers before changing constraints.
  • Remove undocumented server fixes that make environments behave differently from the repository.

This class of error looks like low-level PHP noise, but the management problem is dependency governance. Once Drush is tied to the project and the upgrade path is documented, support becomes more predictable, handovers get easier, and routine maintenance stops turning into forensic work.

If your team is dealing with mixed Drupal versions, fragile deployment scripts, or inherited server fixes, I can help turn that into a supportable operating model without unnecessary platform churn. Talk to Greg about stabilising your Drupal delivery setup.

Need help with this kind of work?

Talk to Greg about stabilising Drupal operations Get in touch with Greg.

Sources

  • Install - Drush
  • Command-line interface / Commands - Composer
  • UPGRADE FROM 4.4 to 5.0 - Symfony
  • drush cr error [#3170166] | Drupal.org
Last modified
2026-06-11

Tags

  • Drupal
  • Drush
  • Composer
  • Symfony
  • php

Review Greg on Google

Greg Nowak Google Reviews

 

  • Support bots need a deletion test before they learn the old help center
  • AI shopping visibility now depends on boring product-data plumbing
  • OpenAI Evals Bring Acceptance Tests to AI Workflow Releases
  • Debugging PHP: A Practical Workflow for Faster Fixes
  • AI Shopping Makes Product Data Integrity a Technical Ops Job
RSS feed

GrN.dk web platforms, web optimization, data analysis, data handling and logistics.