phacility/phabricator · error · PhabricatorWorkerPermanentFailureException

Worker has invalid actor PHID ("%s").

Error message

Worker has invalid actor PHID ("%s").

What it means

loadActor() resolves the job's author PHID to a real user record via PhabricatorPeopleQuery with the omnipotent viewer; when no user matches, the task permanently fails. Bulk jobs execute with their author's authority, so a resolvable author is mandatory.

Source

Thrown at src/infrastructure/daemon/workers/bulk/PhabricatorWorkerBulkJobWorker.php:66

  final protected function loadTask() {
    $id = $this->getTaskID();
    $task = id(new PhabricatorWorkerBulkTask())->load($id);
    if (!$task) {
      throw new PhabricatorWorkerPermanentFailureException(
        pht('Worker has invalid task ID ("%s").', $id));
    }
    return $task;
  }

  final protected function loadActor(PhabricatorWorkerBulkJob $job) {
    $actor_phid = $job->getAuthorPHID();
    $actor = id(new PhabricatorPeopleQuery())
      ->setViewer(PhabricatorUser::getOmnipotentUser())
      ->withPHIDs(array($actor_phid))
      ->executeOne();
    if (!$actor) {
      throw new PhabricatorWorkerPermanentFailureException(
        pht('Worker has invalid actor PHID ("%s").', $actor_phid));
    }

    $can_edit = PhabricatorPolicyFilter::hasCapability(
      $actor,
      $job,
      PhabricatorPolicyCapability::CAN_EDIT);

    if (!$can_edit) {
      throw new PhabricatorWorkerPermanentFailureException(
        pht('Job actor does not have permission to edit job.'));
    }

    // Allow the worker to fill user caches inline; bulk jobs occasionally
    // need to access user preferences.
    $actor->setAllowInlineCacheGeneration(true);

    return $actor;

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Confirm the author user still exists in the People application or user table.
  2. If the user was removed, cancel/delete the job — it can never run without its author.
  3. Custom job-creation code must set AuthorPHID to a valid, durable user (ideally a bot/system account).
Defensive patterns

Strategy: try-catch

Validate before calling

$actor = id(new PhabricatorPeopleQuery())
  ->setViewer(PhabricatorUser::getOmnipotentUser())
  ->withPHIDs(array($author_phid))
  ->executeOne();
if (!$actor) {
  // skip queueing long-running bulk work for a vanished author
}

Try / catch

try {
  // run the bulk worker
} catch (PhabricatorWorkerPermanentFailureException $ex) {
  // author gone: cancel the job instead of retrying
}

Prevention

When it happens

Trigger: The job's author user was deleted while the job was queued; the job's AuthorPHID was set to a non-user PHID (or malformed) by custom job-creation code.

Common situations: Offboarding scripts that delete users with bulk jobs still pending; long-queued jobs surviving account removal; custom importers creating jobs with bogus author PHIDs.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/b3e298b8cad1d4f6. Report an issue: GitHub.