beyondcode / beyondcode/herd-community

[Bug]: herd secure writes invalid Nginx config (empty server.php path) under PHP 8.4, silently failing to secure sites

Open
#1,724 1 comment 0 reactions 0 assignees View on GitHub
macOS
Dominant language
No language data
Stars
122
Forks
1
PR merge metrics
No merged PRs in 30d

Description

### Platform

macOS

### Operating system version

macOS 26.3.1 (25D771280a)

### System architecture

ARM64 (M1, M2, etc)

### Herd Version

1.29.0 (Build: 65)

### PHP Version

PHP 8.4.17 (cli) (built: Jan 16 2026 00:11:29) (NTS)

### Bug description

`herd secure ` reports success but the site is **not** actually secured. In the browser the site continues to load over plain HTTP (or, over HTTPS, is served another site's certificate), and no HTTP→HTTPS redirect happens.

The root cause is an internal failure in `cli/Valet/Herd.php` under PHP 8.4. `valetPath()` does:

```php
$valetPathInfo = $this->runAppleScript('get valet path');
return trim(explode(':', $valetPathInfo)[1]);
```

On this setup `runAppleScript('get valet path')` returns a value that contains no `:`, so `explode(':', $valetPathInfo)[1]` (index 1) does not exist. This produces:

- `Warning: Undefined array key 1 ... cli/Valet/Herd.php on line 105`
- `Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated ... cli/Valet/Herd.php on line 105`

`valetPath()` then returns an **empty string**. That empty path is written into every place the Valet `server.php` path belongs in the generated Nginx site config, so the config ends up with empty replacements:

```nginx
location / {
rewrite ^ "" last; # should be "/Applications/Herd.app/Contents/Resources/valet/server.php"
}
error_page 404 ""; # empty
fastcgi_index ""; # empty
fastcgi_param SCRIPT_FILENAME ""; # empty
```

Nginx rejects this config with `[emerg] empty replacement in .../config/valet/Nginx/:27`, so the reload/restart triggered by `herd secure` **silently fails**. The previously running Nginx keeps serving the old, unsecured config, which is why `secure` claims success while the site is not secured. Because a single invalid site file breaks the whole `include ".../Nginx/*"`, every subsequently secured site is also affected (I found 3 corrupted site configs on my machine).

Expected: `herd secure` should resolve the Valet path robustly (and never write an empty `server.php` path), and it should surface a hard error instead of reporting success when the Nginx reload fails.

The same `explode(':', ...)[1]` / `trim(null)` pattern also fires from `cli/Valet/Herd.php` line 159 during `herd restart`, alongside repeated `file_get_contents(): ... Is a directory` notices from `cli/Valet/Filesystem.php` line 84.

### Steps to reproduce

1. On macOS (Apple Silicon) with PHP 8.4 as the active CLI version.
2. Run `herd secure ` for any linked/parked site.
3. Note the `Undefined array key 1` warning and `trim(): Passing null ...` deprecation from `cli/Valet/Herd.php`.
4. Inspect the generated file `~/Library/Application Support/Herd/config/valet/Nginx/` — the `rewrite`, `error_page 404`, `fastcgi_index`, and `fastcgi_param SCRIPT_FILENAME` values are empty (`""`) instead of the `server.php` path.
5. Run a config test: `"/Applications/Herd.app/Contents/Resources/nginx-arm64" -t -c "~/Library/Application Support/Herd/config/nginx/nginx.conf"` → fails with `[emerg] empty replacement ... :27`.
6. Result: Nginx never reloads the secured config; the site is served unsecured (HTTP 200 with no redirect) and HTTPS falls back to another site's (possibly expired) certificate.

### Relevant log output

Warning: Undefined array key 1 in phar:///Users//Library/Application Support/Herd/bin/herd.phar/cli/Valet/Herd.php on line 105

Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in phar:///Users//Library/Application Support/Herd/bin/herd.phar/cli/Valet/Herd.php on line 105
Restarting Nginx...
The [.test] site has been secured with a fresh TLS certificate.

# nginx -t
[emerg] empty replacement in /Users//Library/Application Support/Herd/config/valet/Nginx/:27
nginx: configuration file .../config/nginx/nginx.conf test failed

# during `herd restart`
Notice: file_get_contents(): Read of 8256 bytes failed with errno=21 Is a directory in phar:///.../cli/Valet/Filesystem.php on line 84
Warning: Undefined array key 1 in phar:///.../cli/Valet/Herd.php on line 159
Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in phar:///.../cli/Valet/Herd.php on line 159

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in cli/Valet/Herd.php at valetPath() around lines 105 and 159, then inspect the generated file under ~/Library/Application Support/Herd/config/valet/Nginx/. Check cli/Valet/Filesystem.php line 84 for the restart notice. Run the provided nginx -t command; done means secure no longer writes empty server.php paths and a failed reload is surfaced instead of reported as success.

Written by the indexing model from the issue text.

Assessment

Tech stack
nginx, php
Domain
backend, cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.