Skip to content

[Bug]: Herd keeps injecting itself in the $PATH even if it's already added #1722

Description

@brtdv

Platform

macOS

Operating system version

macOS 15.7.7 / 26

System architecture

ARM64 (M1, M2, etc)

Herd Version

1.29.0

PHP Version

No response

Bug description

I opened #187 about this back in 2023. It got labelled fixed-in-next-release and closed in August 2024, but it never went away. People kept commenting on it through 2025, and it's still there on 1.29.0. Since that issue is locked, here's a new one.

What's wrong

Herd decides whether it already configured your shell by looking for the exact line it wrote. Change anything about that line and the check fails, so Herd appends a second copy on the next launch. Same story with the HERD_PHP_*_INI_SCAN_DIR variables: define them yourself and Herd will still add its own block at the bottom, so now they're set twice.

For some people this happens on every launch. Someone in #187 found ten copies in one .bash_profile.

Why anyone would touch that line

The trailing slash, for one. With export PATH="$HOME/Library/Application Support/Herd/bin/":$PATH, which php prints /Users/me/Library/Application Support/Herd/bin//php. Harmless, but ugly enough that people fix it.

The bigger reason is $PATH order. If you want to combine Herd with Homebrew PHP, or with something like LocalWP that ships its own PHP, you need Herd at the end of $PATH instead of the front. You can edit that, but it won't survive the next launch.

And if you keep your dotfiles in git, you get to discard Herd's changes every time you start the app.

Reproducing it

Move the Herd line to the end of $PATH in your ~/.zshrc:

export PATH=$PATH:"$HOME/Library/Application Support/Herd/bin/"

Quit Herd, start it again. There are now two Herd blocks in the file, and Herd is back at the front of $PATH.

What would fix it

Match on the directory instead of the string. Split $PATH on :, expand $HOME, drop trailing slashes, and skip the injection if Herd's bin is anywhere in there. For the HERD_PHP_*_INI_SCAN_DIR variables, just check whether the variable is set rather than whether your exact block is present.

Better still is what @markjaquith suggested in #187: put the real configuration in its own file, say ~/.herdrc, and inject a single [ -f ~/.herdrc ] && source ~/.herdrc line into ~/.zshrc. Then Herd can rewrite its own file as much as it likes, and I can move that one line wherever I need it without the app undoing my work.

While you're in there, dropping the trailing slash would clean up which php too.

Environment

  • macOS:
  • Architecture: ARM64
  • Herd version:
  • Shell: zsh

Steps to reproduce

No response

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions