phacility/phabricator · error · PhabricatorWorkerPermanentFailureException

Failed to load import with PHID "%s".

Error message

Failed to load import with PHID "%s".

What it means

PhabricatorCalendarImportReloadWorker looks up the calendar import by the PHID stored in the task data; when the lookup fails it throws PhabricatorWorkerPermanentFailureException, which retires the task permanently instead of retrying. This is the correct outcome for a deleted import — retrying can never succeed.

Source

Thrown at src/applications/calendar/worker/PhabricatorCalendarImportReloadWorker.php:45

      array(
        'via' => idx($data, 'via', self::VIA_TRIGGER),
      ));

    $import_engine->importEventsFromSource($author, $import, false);
  }

  private function loadImport() {
    $viewer = PhabricatorUser::getOmnipotentUser();

    $data = $this->getTaskData();
    $import_phid = idx($data, 'importPHID');

    $import = id(new PhabricatorCalendarImportQuery())
      ->setViewer($viewer)
      ->withPHIDs(array($import_phid))
      ->executeOne();
    if (!$import) {
      throw new PhabricatorWorkerPermanentFailureException(
        pht(
          'Failed to load import with PHID "%s".',
          $import_phid));
    }

    return $import;
  }

}

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Treat it as expected noise: log and ignore PhabricatorWorkerPermanentFailureException for deleted imports
  2. Before queueing the worker, verify the import still exists (query by PHID) to avoid queuing work for rows deleted in the same request
  3. If imports are vanishing unexpectedly, audit who/what deletes them (daemon log, herald rules) rather than retrying the task

Example fix

// before
$this->yieldToClusterQueueForImport($import);

// after: confirm the row exists before queuing the reload task
$import = id(new PhabricatorCalendarImportQuery())
  ->setViewer(PhabricatorUser::getOmnipotentUser())
  ->withPHIDs(array($phid))
  ->executeOne();
if ($import) {
  PhabricatorWorker::scheduleTask(
    'PhabricatorCalendarImportReloadWorker',
    array('importPHID' => $import->getPHID()));
}
Defensive patterns

Strategy: validation

Validate before calling

$import = id(new PhabricatorCalendarImportQuery())
  ->setViewer(PhabricatorUser::getOmnipotentUser())
  ->withPHIDs(array($import_phid))
  ->executeOne();
if (!$import) {
  // Import deleted before scheduling: skip queuing the task entirely.
  return;
}
PhabricatorWorker::scheduleTask(
  'PhabricatorCalendarImportReloadWorker',
  array('importPHID' => $import->getPHID()));

Try / catch

// Permanent failures are terminal by design: do not retry them.
try {
  $worker->executeTask();
} catch (PhabricatorWorkerPermanentFailureException $ex) {
  phlog('Import reload skipped (import no longer exists): '.$ex->getMessage());
}

Prevention

When it happens

Trigger: The import was deleted by the user between the time the task was queued and when a worker picked it up; Task data was written with a stale, typo'd, or fabricated importPHID; A task was requeued from an old dump after the DB row was purged

Common situations: Users deleting an ICS feed import while its refresh worker is still in the queue; bulk imports cancelled mid-flight; manual task-data manipulation during debugging.

Related errors


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