Resubscribe Link Errors

Your software
My Mautic version is: v3.2.2
My PHP version is: 7.3.20
My Database type and version is: MySQL 8.0.19

Your problem
When a user clicks the “resubscribe” link on the unsubscribe page it displays the Mautic 500 error page. It does, however, resubscribe the user. The following error is output to the error log.

These errors are showing in the log:

[2021-01-25 09:57:03] mautic.CRITICAL: Uncaught PHP Exception Mautic\CoreBundle\Exception\BadConfigurationException: " is missing a required config file" at /var/www/html/app/bundles/CoreBundle/Templating/Helper/ThemeHelper.php line 64 {"exception":"[object] (Mautic\\CoreBundle\\Exception\\BadConfigurationException(code: 0):  is missing a required config file at /var/www/html/app/bundles/CoreBundle/Templating/Helper/ThemeHelper.php:64)"} []

Steps I have tried to fix the problem:
I thought it might be a template issue, based on the error message, so I switched the “default template” back to the “blank” template, but it didn’t help. I also tried setting the “default template” to a couple of the other built-in templates, but that didn’t help either.

Templating in this case does not mean what you think it does. Its a collection of standard configurations for some of the operations withing Mautic. In your logs are there any permissions errors related to this? I have seen the exact behavior you describe and the fix is to reset permissions on mautic/var/logs. I have been unable to determine why this happens sporadically so I set a cron to chown the log directory regularly and many of my errors never reappeared.

@EJL Permissions/owners all look ok and that error message is the only error message in the logs. The permission/owners of the files in var/log is:

 -rw-r--r-- 1 www-data www-data   

for all the files in there. The var and log directories have the same owner as well, www-data.

In a Dev environment only: set permissions to 777 or rwxrwxrwx and test to see if it works. Be sure to walk your permissions back after testing to the minimums.

Thanks for the suggestion, but it didn’t make any difference.

So looking at the file:

/var/www/html/app/bundles/CoreBundle/Templating/Helper/ThemeHelper.php

and line 64 as per the error message, it does appear to be related to the “theme”:

        if (file_exists($this->themePath.'/config.json')) {
            $this->config = json_decode(file_get_contents($this->themePath.'/config.json'), true);
        } else {
            throw new BadConfigurationException($this->theme.' is missing a required config file');
        }

Line 64 is the throw new line above, which reading the logic seems to be suggesting the “theme” is missing the config.json, which it isn’t, so I’m guessing the $this->themePath must be wrong somehow, which if I’m reading the error message and code right, is set to an empty string.

So, reading the code a bit more, it is the $this->theme that is blank, which is set from the value passed into the constructor, which in turn means it is looking for the config.json in /var/www/html/themes/ instead of the actual theme directory, so this feels like a bug in the code.

If I override line 51 in /var/www/html/app/bundles/CoreBundle/Templating/Helper/ThemeHelper.php from:

        $this->theme     = $theme;

to

        $this->theme     = 'oxygen';

Then the unsubscribe page loads, but obviously, this is not a solution but proves that where the constructor is being called from, it isn’t passing in the theme name. My PHP knowledge, unfortunately, is not good enough to trace this back and find where the bad call is, but I think this proves it is a bug, so I’ll raise a ticket on GitHub for it.

Probably a bit late now, but I was also experiencing this issue.

It appears to relate to line 374 of app/bundles/EmailBundle/Controller/PublicController.php.

$email->getTemplate()

was returning null in my implementation (I think this is because we use the API to directly apply HTML to an email rather than using a template in the Mautic UI). As a result, the $template variable was being set to null, which seemed to eventually to cause an empty $theme to be passed in the ThemeHelper constructor.

I was able to fix it by adding a check for $email->getTemplate() to be null, so now my line 374 looks like this:

$template = (null !== $email && null !== $email->getTemplate() && 'mautic_code_mode' !== $email->getTemplate()) ? $email->getTemplate() : $this->coreParametersHelper->get('theme');

Thanks @da644 for pointing me in the right direction!

@ebehlmann It might be worth creating a pull request for that change so it gets fixed in core for everyone :slight_smile: