Environment
- Add-on: ddev-drupal-code-quality
- OS: macOS (Apple Silicon), ddev at
/opt/homebrew/bin/ddev
- IDE: VS Code / VS Codium PHPStan extension, with
phpstan.binPath pointed at .ddev/drupal-code-quality/tooling/bin/phpstan
What happens
The IDE spawns the host shim (e.g. tooling/bin/phpstan), which delegates to ddev-run. ddev-run ends in:
exec ddev "$tool_name" "$@"
When the IDE was launched from the Dock/Spotlight (not from a shell), the process PATH is the minimal launchd default (/usr/bin:/bin:/usr/sbin:/sbin) and does not include /opt/homebrew/bin. Result:
ddev-run: line 40: exec: ddev: not found
The tools work fine from the terminal because the interactive shell PATH includes the ddev install dir. So this only bites IDE integrations — exactly the use case the shims exist for.
Root cause
The shim relies on ddev being resolvable via PATH. GUI-launched processes on macOS (launchd) and Linux (systemd) do not inherit the login shell PATH, so this assumption fails.
Suggested fix
Harden ddev-run to locate ddev even with a minimal PATH. After the cd "$repo_root" line:
# IDEs on macOS (launchd) / Linux (systemd) spawn tools with a minimal PATH
# that omits Homebrew and other common install dirs, so \`ddev\` on PATH
# cannot be assumed. Resolve it robustly before exec.
if ! command -v ddev >/dev/null 2>&1; then
for candidate in /opt/homebrew/bin /usr/local/bin "$HOME/.ddev/bin" /opt/ddev/bin; do
if [ -x "$candidate/ddev" ]; then
PATH="$candidate:$PATH"
break
fi
done
fi
if ! command -v ddev >/dev/null 2>&1; then
echo "ddev-run: cannot locate the 'ddev' binary on PATH or in common install dirs." >&2
echo "Add ddev's directory to your IDE's PATH, or install ddev to a standard location." >&2
exit 127
fi
This keeps PATH-based resolution as the happy path and only falls back to known install locations, with a clear error if ddev genuinely isn't installed.
Workaround for users
Launch the editor from a terminal (e.g. codium .), or set a login-wide PATH on macOS:
sudo launchctl config user path "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
(then reboot).
Environment
/opt/homebrew/bin/ddevphpstan.binPathpointed at.ddev/drupal-code-quality/tooling/bin/phpstanWhat happens
The IDE spawns the host shim (e.g.
tooling/bin/phpstan), which delegates toddev-run.ddev-runends in:When the IDE was launched from the Dock/Spotlight (not from a shell), the process
PATHis the minimal launchd default (/usr/bin:/bin:/usr/sbin:/sbin) and does not include/opt/homebrew/bin. Result:The tools work fine from the terminal because the interactive shell
PATHincludes the ddev install dir. So this only bites IDE integrations — exactly the use case the shims exist for.Root cause
The shim relies on
ddevbeing resolvable viaPATH. GUI-launched processes on macOS (launchd) and Linux (systemd) do not inherit the login shellPATH, so this assumption fails.Suggested fix
Harden
ddev-runto locateddeveven with a minimalPATH. After thecd "$repo_root"line:This keeps PATH-based resolution as the happy path and only falls back to known install locations, with a clear error if ddev genuinely isn't installed.
Workaround for users
Launch the editor from a terminal (e.g.
codium .), or set a login-wide PATH on macOS:sudo launchctl config user path "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"(then reboot).