phacility/phabricator · error · PhabricatorWorkerPermanentFailureException

No related users have linked Asana accounts.

Error message

No related users have linked Asana accounts.

What it means

The Asana feed worker publishes Phabricator stories (task/revision updates) to Asana on behalf of related users. It collects the owner, active/passive reviewers, and CCs, maps their PHIDs to linked Asana accounts via lookupAsanaUserIDs(), and throws PhabricatorWorkerPermanentFailureException when that map comes back empty. Permanent failure means the daemon will not retry — the queued story task is dropped, because no linked Asana user exists to publish through.

Source

Thrown at src/applications/doorkeeper/worker/DoorkeeperAsanaFeedWorker.php:67

    //     revision.
    //   - Follow: users who are following the object; generally CCs.

    $owner_phid = $publisher->getOwnerPHID($object);
    $active_phids = $publisher->getActiveUserPHIDs($object);
    $passive_phids = $publisher->getPassiveUserPHIDs($object);
    $follow_phids = $publisher->getCCUserPHIDs($object);

    $all_phids = array();
    $all_phids = array_merge(
      array($owner_phid),
      $active_phids,
      $passive_phids,
      $follow_phids);
    $all_phids = array_unique(array_filter($all_phids));

    $phid_aid_map = $this->lookupAsanaUserIDs($all_phids);
    if (!$phid_aid_map) {
      throw new PhabricatorWorkerPermanentFailureException(
        pht('No related users have linked Asana accounts.'));
    }

    $owner_asana_id = idx($phid_aid_map, $owner_phid);
    $all_asana_ids = array_select_keys($phid_aid_map, $all_phids);
    $all_asana_ids = array_values($all_asana_ids);

    // Even if the actor isn't a reviewer, etc., try to use their account so
    // we can post in the correct voice. If we miss, we'll try all the other
    // related users.

    $try_users = array_merge(
      array($data->getAuthorPHID()),
      array_keys($phid_aid_map));
    $try_users = array_filter($try_users);

    $access_info = $this->findAnyValidAsanaAccessToken($try_users);
    list($possessed_user, $possessed_asana_id, $oauth_token) = $access_info;

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Have at least one directly related user (owner/reviewer/subscriber) link their Asana account in Settings -> External Accounts
  2. Confirm the Asana auth provider and asana.workspace-id are configured so the linking flow works
  3. If the bridge is unwanted, disable the Doorkeeper Asana feed worker so stories are not queued
  4. Re-trigger publishing by causing a new story on the object after accounts are linked
Defensive patterns

Strategy: fallback

Validate before calling

// Before publishing to Asana, check that at least one related user has a linked account.
$accounts = id(new PhabricatorExternalAccountQuery())
  ->setViewer(PhabricatorUser::getOmnipotentUser())
  ->withAccountTypes(array('asana'))
  ->withUserPHIDs($all_phids)
  ->execute();
if (!$accounts) {
  // Skip Asana mirroring for this story instead of enqueueing a doomed task.
  return;
}

Prevention

When it happens

Trigger: A feed story whose object's related users (owner + reviewers + subscribers + author-adjacent PHIDs) have zero linked Asana accounts in Phabricator. Fires even if some unrelated users have Asana linked; only related-user linkage counts.

Common situations: Enabling the Asana bridge before any of the team has linked accounts under Settings -> External Accounts; a one-person project whose owner never linked Asana; testing with personal test objects where only the admin (not the owner) has a linked account.

Related errors


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