This is a bug in the core plugin System - Task Notification. You can see it in the path (plugins/system/tasknotification
) referenced in the error.
Reproduction:
Create a scheduled task of any type. It does not have to be something related to Akeeba software; the problem is reproducible with the core task type "Global Check In". Go to the Advanced tab and set Task Success to Enabled. In the User Groups to Notify option right below Task Success remove all groups and click on Save & Close.
Execute the task, either automatically or manually.
Expected result:
Task runs without error.
Actual Result:
Task fails with error:
Joomla\Plugin\System\TaskNotification\Extension\TaskNotification::sendMail(): Argument #4 ($gr
oups) must be of type array, null given, called in /path/to/my/joomla5/site/plugins/system/
tasknotification/src/Extension/TaskNotification.php on line 200
Technical Explanation:
There's a glaring bug in lines 196 and 200 of the plugin. In line 196 there is no second parameter to the get()
call. As a result, when no user groups have been defined the value retrieved is NULL
. This value is then passed in line 200 without any further checks as the fourth argument to the private sendMail
method. However, this parameter excepts an array and Joomla is passing it a NULL. This triggers a PHP TypeError
exception.
Technical Solution:
The correct solution is for Joomla to change line 196 of plugins/system/tasknotification/src/Extension/TaskNotification.php
from this
$groups = $task->get('params.notifications.notification_success_groups');
to this
$groups = $task->get('params.notifications.notification_success_groups', []) ?: [];
The two additions do the following:
- The
, []
in the get()
call tells Joomla to use the default value []
(empty array) instead of NULL
when the task was last saved before the introduction of notifications (or, more generally, created when the System - Task Notification plugin was not active).
- The
?: []
is a further protection that's not technically necessary. If someone edits the database directly and modifies the JSON configuration data of the task so that the notification_success_groups
parameter is an empty string (""
) instead of an empty array ([]
) it will catch the mistake and cast it to an empty array.
Additionally, I would propose that line 200 is changed to:
$this->sendMail('plg_system_tasknotification.success_mail', $data, $outFile, $groups ?: []);
This is not necessary in the current codebase, but it's good practice to introduce error-catching here in case someone, sometime in the future, changes how $groups
is determined and reintroduces a NULL
return (or, worse, an empty string or integer 0 return).
Mitigation:
(In other words, what can you do until this is properly fixed.)
Open your Scheduled Task.
Click on the Advanced tab.
If you want to receive success notifications:
- Set Task Success to No
- Click on Save
- Set Task Success to Yes
- Confirm that User Groups to Notify under Task Success is non-empty (by default, it should show Super Users)
- Click on Save & Close
Note: it is very important that you do both saves described above, even if you think they're not necessary. The more confusing aspect of this issue is that when the User Groups To Notify is actually empty in the database the interface displays it as "Super User" being selected, misleading you into thinking it's not actually empty.
This is a side-effect of how Joomla's multi-select field works. If it is given an empty value (NULL, empty string, empty array, integer 0, or any other value which PHP would consider satisfying the empty()
built-in functions condition) it will show the default setting hard-coded in the form's XML file. This is necessary for new items which have not been saved yet to display the default values. However, this means that you can never see the field getting empty, unless the developer has deliberately included an "empty option" i.e. an option which has a value equal to the empty string. This is why, for example, you see items like "- Select a group -" elsewhere in Joomla and 3PD extensions; these are the "empty options" allowing you to simulate an empty list.
The other side-effect is what Joomla does when you delete all options from a multi-select. Instead of saving an empty array ([]
) in the database… it simply omits this parameter altogether when saving the form data. This makes sense as it makes the stored data far more compact, saving you database bloat, but at the same time it relies on the developer remembering to pass the second option to get()
to tell Joomla what the default option is, as well as remembering to change that second option whenever the default item is changed in the XML. This is extremely error-prone, which is why we are abstracting this with great effort in our custom forms in Admin Tools and Akeeba Backup for example. But, I digress.
A plea for help
Unfortunately, Joomla has chosen to block me from contributing bug fixes to their software. Even though I know what the (fairly trivial) oversight is and how to fix it, I am allowed to neither report it, nor contribute a fix to it. A bug report is already opened in https://github.com/joomla/joomla-cms/issues/45488. Please, do add a link to this public ticket in there so the real issue is fixed. Thank you in advance!
Nicholas K. Dionysopoulos
Lead Developer and Director
🇬🇷Greek: native 🇬🇧English: excellent 🇫🇷French: basic • 🕐 My time zone is Europe / Athens
Please keep in mind my timezone and cultural differences when reading my replies. Thank you!