Laravel uses the vlucas/phpdotenv package to manage its environment.
It's pretty well known that if you have a space on either side the = sign in a key value pair then the .env file is invalid, but I had checked for this (and checked again).
Laravel will try to use its standard logging methods before they have actually had a chance to be booted up with the result that you're left with a "reflection error" exception message on the CLI rather than the actual cause of the problem in the dotenv package.
Debugging this is not trivial and I resorted to using strace to try and determine exactly what was going on. Don't do this at home kids! The easier solution is at the end of the article.
I used the following command to generate a trace of the system calls being made by PHP while trying (and failing) to run artisan optimize.
strace php artisan optimize &> /tmp/strace.txt
That let me walk through the calls and eventually confirm that the first PHP exception was thrown in the package that deals with reading the environment file.
access("/var/www/raffle.bhf.org.uk.new/vendor/vlucas/phpdotenv/src/Dotenv.php", F_OK) = 0 ... more lines loading up more of the package and showing us processing it .... access("/var/www/raffle.bhf.org.uk.new/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php", F_OK) = 0
But sadly there was no indication of exactly what the problem is with the file!
I decided that creating a minimal project dedicated to debugging my .env file was going to be faster than anything else.
I created a temporary directory and ran "composer require vlucas/phpdotenv". Then I placed my faulty .env file into the directory and ran the following PHP file:
<?php require('vendor/autoload.php'); $dotenv = new Dotenv\Dotenv(__DIR__); $dotenv->load();
This gave me the actual exception in DotEnv which was that "Dotenv values containing spaces must be surrounded by quotes". So it wasn't a space around the = sign but rather a space in one of my values, which made my life a lot easier! As an extra bonus the first line in the stack showed exactly which key was problematic.