Undefined array key instance in ArgumentsResolver.php
In the last few days, I was fighting hard to understand and fix an error that occurred when trying to deploy a Magento upgrade in production for one of our merchants.
During the setup:di:compile
phase our CI pipeline crashed with the error Undefined array key "instance" in ArgumentsResolver.php on line 171
.
Since the error always occurred when trying to deploy to production and since I could reproduce the error when trying to run setup:di:compile
manually on the production server, I tried my best to search for the issue on GitHub and on Google. It surprised me that I was not able to find much regarding this error.
The first StackOverflow thread I came across simply suggested wrapping the code in an if statement which sounded completely wrong:
if(isset($this->getInstanceArgument($config['instance'])))
{
$argument = $this->getInstanceArgument($config['instance']);
}
So I did not go this path and after a while, I found another StackOverflow thread with some additional debugging ideas. One of the contributors demonstrated how to debug the issue and figured out that this was a problem if you are using a module that references Magento\Variable\Model\Source\Variables
instead of the new Magento\Variable\Model\Config\Structure\AvailableVariables
alternative.
In his debugging example, he figured out the issue can be caused by an older version of the firegento/firegento-magesetup2 module in combination with Magento 2.4.3 or later. Since we upgraded that module already and since the error did not happen in our development environments or on the staging server, it had to be something different. Also, none of our code and no 3rd party code was using Magento\Variable\Model\Source\Variables
at all. So back to square one.
I posted the problem in the Magento Community Engineering slack and Julian Nuß got me one step on the right track: Flush the Redis cache. In my initial experiments, I only flushed the file system cache and that had no effect. And since the staging environment is not using Redis but the production environment is, this sounded like it could really be the source of the problem. So I tried flushing the Redis cache (plus the file systems caches just to be sure) and setup:di:compile
worked. YEAH!
Great I thought, let's kick off the CI pipeline again and call it a day. And again, the CI pipeline failed. I ran setup:di:compile
manually again and it also failed. I didn't really know what else to do. I decided to stop the webserver just to be sure no other requests are interfering with the setup:di:compile
process. But also that had no effect. While tailing through various logfiles, it finally occurred to me: The cron jobs are still running, and they are still running against the old deployed version of Magento. So I disabled the crons, cleared all caches, flushed Redis, and ran setup:di:compile
and it worked. I ran the command multiple times in a row, it worked all the time. I decided to run our CI pipeline again and that worked. Problem solved.
And as always in the end it all made sense. StackOverflow contributor Tu Van - who also replied to my question in Slack - was right. Some code was using the old Magento\Variable\Model\Source\Variables
. However, it was not code in the current deployment but code in the last production deployment. When the caches are empty Magento will generate what's needed on each incoming request (or when cron runs) and since the old and the new deployment "shared" the same Redis instance, that caused the interference during the setup:di:compile
run.
Big thanks to Tu Van & Julian Nuß for putting me on the right track!