{"record":{"id":"20dcf188ff02c6f5","repo":"phacility/phabricator","slug":"worker-has-invalid-job-id-s","errorCode":null,"errorMessage":"Worker has invalid job ID (\"%s\").","messagePattern":"Worker has invalid job ID \\(\"(.+?)\"\\)\\.","errorType":"exception","errorClass":"PhabricatorWorkerPermanentFailureException","httpStatus":null,"severity":"error","filePath":"src/infrastructure/daemon/workers/bulk/PhabricatorWorkerBulkJobWorker.php","lineNumber":43,"sourceCode":"\n  final protected function getTaskID() {\n    $data = $this->getTaskData();\n    $id = idx($data, 'taskID');\n    if (!$id) {\n      throw new PhabricatorWorkerPermanentFailureException(\n        pht('Worker has no task ID.'));\n    }\n    return $id;\n  }\n\n  final protected function loadJob() {\n    $id = $this->getJobID();\n    $job = id(new PhabricatorWorkerBulkJobQuery())\n      ->setViewer(PhabricatorUser::getOmnipotentUser())\n      ->withIDs(array($id))\n      ->executeOne();\n    if (!$job) {\n      throw new PhabricatorWorkerPermanentFailureException(\n        pht('Worker has invalid job ID (\"%s\").', $id));\n    }\n    return $job;\n  }\n\n  final protected function loadTask() {\n    $id = $this->getTaskID();\n    $task = id(new PhabricatorWorkerBulkTask())->load($id);\n    if (!$task) {\n      throw new PhabricatorWorkerPermanentFailureException(\n        pht('Worker has invalid task ID (\"%s\").', $id));\n    }\n    return $task;\n  }\n\n  final protected function loadActor(PhabricatorWorkerBulkJob $job) {\n    $actor_phid = $job->getAuthorPHID();\n    $actor = id(new PhabricatorPeopleQuery())","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/daemon/workers/bulk/PhabricatorWorkerBulkJobWorker.php#L25-L61","documentation":"loadJob() takes the jobID from task data and loads the PhabricatorWorkerBulkJob via an omnipotent-user query; if no row matches, the task permanently fails with this message. Because the query runs as the omnipotent user, policies can never cause this — only the row's absence (deleted job or wrong ID) can.","triggerScenarios":"The bulk job was deleted before its worker task ran; jobID in the task data points at a nonexistent row after data corruption or a partial database restore that kept worker tasks but dropped job rows.","commonSituations":"Admins deleting queued bulk jobs; partial restores; long queue backlogs where tasks outlive the jobs they reference.","solutions":["Check whether the bulk job still exists (bulk job UI or the phabricator_worker_bulk_job table).","If it was deleted intentionally, the permanent failure is correct — archive/dispose of the failed task.","If the job should exist, restore the missing row or fix the referenced ID, then re-queue the task.","Keep taskmaster throughput healthy so tasks do not outlive their jobs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"$job = id(new PhabricatorWorkerBulkJobQuery())\n  ->setViewer(PhabricatorUser::getOmnipotentUser())\n  ->withIDs(array($job_id))\n  ->executeOne();\nif (!$job) {\n  // do not queue the worker task\n}","typeGuard":null,"tryCatchPattern":"try {\n  // run the bulk worker\n} catch (PhabricatorWorkerPermanentFailureException $ex) {\n  // expected when the job row is gone: log and archive the task\n}","preventionTips":["Cancel bulk jobs instead of deleting them while worker tasks are queued.","Keep taskmaster throughput healthy so tasks do not outlive jobs.","Avoid partial restores that keep worker rows but drop job rows."],"tags":["phabricator","bulk-jobs","worker-queue","data-integrity"],"backgroundTag":"entity-not-found","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}