No Code Attached Yet
avatar bhuvan-somisetty
bhuvan-somisetty
23 Aug 2026

Steps to reproduce the issue

In Joomla's Scheduled Tasks component (com_scheduler), Joomla\Component\Scheduler\Administrator\Model\TaskModel::getTask() is responsible for acquiring a lock on the next scheduled task from the queue and returning the task record for execution.

When getTask() executes without an explicit task id (e.g., standard background queue runner or webcron):

$scheduler = new \Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler();
$task      = $scheduler->getTask();

Inside TaskModel::getTask():

  1. getNextTaskId() calls $db->setQuery($idQuery)->loadColumn(), which returns an array (e.g., ['1']).
  2. $lockQuery->where($db->quoteName('id') . ' = :taskId')->bind(':taskId', $id, ParameterType::INTEGER) binds the array directly to a scalar :taskId integer placeholder.
  3. fetchTask($db, $now) attempts to fetch the locked task by running WHERE locked = :now instead of querying by the specific primary key id.
  4. If loadObject() returns null, fetchTask() immediately accesses $task->execution_rules without a null check.

Version

5.4-dev / 6.0-dev / 6.1-dev / 6.2-dev

Expected result

  1. getNextTaskId() should return a scalar integer (or scalar task ID should be extracted) and cleanly bind to :taskId as ParameterType::INTEGER.
  2. fetchTask() should retrieve the task by its specific primary key (WHERE id = :taskId) that was just locked, rather than by a non-unique timestamp (WHERE locked = :now).
  3. fetchTask() should safely handle cases where the task record is null without throwing a fatal error.
  4. getNextTaskId() should filter out tasks that are already locked (locked IS NULL) so running tasks are not re-selected from the queue.

Actual result

  1. Parameter Binding Type Mismatch: $lockQuery->bind(':taskId', $id, ParameterType::INTEGER) binds an array to a single named parameter placeholder :taskId, causing driver warnings or parameter binding failures.
  2. Race Condition & Non-Deterministic Task Retrieval: Querying WHERE locked = :now in fetchTask() can match multiple tasks if runners/webcrons execute at the same second, causing loadObject() to return an arbitrary task instead of the one just acquired.
  3. Fatal Error on Null Task: If loadObject() returns null, lines 564–566 throw a fatal PHP 8 error: Attempt to modify property "execution_rules" on null.
  4. Duplicate Task Execution: getNextTaskId() does not check WHERE locked IS NULL, allowing already-running tasks to be re-selected while executing.

System Information

Joomla 5.4-dev / 6.0-dev / 6.1-dev / 6.2-dev
PHP 8.2 / 8.3 / 8.4

Additional Comments

Root Cause:
In administrator/components/com_scheduler/src/Model/TaskModel.php:

  • Line 391 & 535: $id is returned as an array from loadColumn() but passed directly to bind(':taskId', $id, ParameterType::INTEGER).
  • Line 555: fetchTask($db, $now) queries by timestamp :now rather than by $taskId.
  • Lines 564–566: $task->execution_rules is accessed without verifying $task !== null.
  • Line 529: getNextTaskId lacks a where($db->quoteName('locked') . ' IS NULL') clause.
avatar bhuvan-somisetty bhuvan-somisetty - open - 23 Aug 2026
avatar joomla-cms-bot joomla-cms-bot - change - 23 Aug 2026
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 23 Aug 2026
avatar joomdonation
joomdonation - comment - 24 Aug 2026

I'm closing this issue as it is invalid as described here #48292 (comment)

avatar joomdonation joomdonation - change - 24 Aug 2026
Status New Closed
Closed_Date 0000-00-00 00:00:00 2026-08-24 14:15:10
Closed_By joomdonation
avatar joomdonation joomdonation - close - 24 Aug 2026

Add a Comment

Login with GitHub to post a comment