phacility/phabricator · error · PhabricatorWorkerPermanentFailureException
Worker has no job ID.
Error message
Worker has no job ID.
What it means
Bulk job workers receive their job identity through the 'jobID' key of the worker task data; getJobID() permanently fails the task when that key is missing or falsy. Core always sets jobID when queuing, so hitting this means a custom scheduler queued a bulk worker class directly with wrong or missing task data.
Source
Thrown at src/infrastructure/daemon/workers/bulk/PhabricatorWorkerBulkJobWorker.php:20
abstract class PhabricatorWorkerBulkJobWorker
extends PhabricatorWorker {
final protected function acquireJobLock() {
return PhabricatorGlobalLock::newLock('bulkjob.'.$this->getJobID())
->lock(15);
}
final protected function acquireTaskLock() {
return PhabricatorGlobalLock::newLock('bulktask.'.$this->getTaskID())
->lock(15);
}
final protected function getJobID() {
$data = $this->getTaskData();
$id = idx($data, 'jobID');
if (!$id) {
throw new PhabricatorWorkerPermanentFailureException(
pht('Worker has no job ID.'));
}
return $id;
}
final protected function getTaskID() {
$data = $this->getTaskData();
$id = idx($data, 'taskID');
if (!$id) {
throw new PhabricatorWorkerPermanentFailureException(
pht('Worker has no task ID.'));
}
return $id;
}
final protected function loadJob() {
$id = $this->getJobID();
$job = id(new PhabricatorWorkerBulkJobQuery())View on GitHub (pinned to 5720a38cfe)
Solutions
- Schedule bulk workers with array('jobID' => $job->getID()) (plus 'taskID' where the worker needs it).
- Prefer the job's own queue/confirm flow rather than scheduleTask() on the worker class.
- Align custom schedulers' task-data keys with core's expectations.
Example fix
// before
PhabricatorWorker::scheduleTask(
'PhabricatorWorkerBulkJobCreateWorker',
array());
// after
PhabricatorWorker::scheduleTask(
'PhabricatorWorkerBulkJobCreateWorker',
array('jobID' => $job->getID())); Defensive patterns
Strategy: validation
Validate before calling
if (!idx($task_data, 'jobID')) {
throw new InvalidArgumentException(
'Bulk worker task data requires a jobID.');
}
PhabricatorWorker::scheduleTask($bulk_worker_class, $task_data); Type guard
function bulk_task_data_has_job_id($data) {
return is_array($data) && !empty($data['jobID']);
} Prevention
- Always schedule bulk workers with array('jobID' => ...).
- Use the job's own pipeline instead of scheduleTask() on worker classes.
- Keep task-data keys identical to core's when subclassing bulk workers.
When it happens
Trigger: Calling PhabricatorWorker::scheduleTask() on PhabricatorWorkerBulkJobCreateWorker (or a custom PhabricatorWorkerBulkJobWorker subclass) with a data array that lacks 'jobID', or where the jobID value is 0/null.
Common situations: Custom code queuing bulk workers directly instead of going through PhabricatorWorkerBulkJob's own queue pipeline; refactors that renamed or dropped the task-data key.
Related errors
- Worker has no task ID.
- No "%s" in task data.
- Expected task data to be a dictionary.
- Found unexpected job status ("%s").
- Found unexpected task status ("%s").
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/ad1294d28e1255d1.
Report an issue: GitHub.