phacility/phabricator · error · Exception

No such token "%s"!

Error message

No such token "%s"!

What it means

PhabricatorTokenGivenEditor::validateToken() loads the token by PHID with the acting user as viewer. If PhabricatorTokenQuery returns nothing (bad PHID, deleted token, or a token invisible to the actor), giving that token is refused before any write occurs.

Source

Thrown at src/applications/tokens/editor/PhabricatorTokenGivenEditor.php:153

      $token_given->delete();

      queryfx(
        $token_given->establishConnection('w'),
        'INSERT INTO %T (objectPHID, tokenCount) VALUES (%s, 0)
          ON DUPLICATE KEY UPDATE tokenCount = tokenCount - 1',
        id(new PhabricatorTokenCount())->getTableName(),
        $object->getPHID());
    $token_given->saveTransaction();
  }

  private function validateToken($token_phid) {
    $token = id(new PhabricatorTokenQuery())
      ->setViewer($this->requireActor())
      ->withPHIDs(array($token_phid))
      ->executeOne();

    if (!$token) {
      throw new Exception(pht('No such token "%s"!', $token_phid));
    }

    return $token;
  }

  private function validateObject($object_phid) {
    $object = id(new PhabricatorObjectQuery())
      ->setViewer($this->requireActor())
      ->withPHIDs(array($object_phid))
      ->executeOne();

    if (!$object) {
      throw new Exception(pht('No such object "%s"!', $object_phid));
    }

    return $object;
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Re-fetch the current token list with PhabricatorTokenQuery and submit a PHID from those results
  2. Drop cached token PHIDs and resolve them fresh per session
  3. If the actor cannot see the token, act as a viewer with appropriate visibility

Example fix

// before: hardcoded, possibly stale token PHID
$editor->giveTokenTo($object_phid, 'PHID-TOKN-stale');

// after: resolve a live token first
$tokens = id(new PhabricatorTokenQuery())
  ->setViewer($actor)
  ->execute();
$token = head($tokens);
$editor->giveTokenTo($object_phid, $token->getPHID());
Defensive patterns

Strategy: validation

Validate before calling

$token = id(new PhabricatorTokenQuery())
  ->setViewer($actor)
  ->withPHIDs(array($token_phid))
  ->executeOne();
if (!$token) {
  // re-resolve from the current token list instead of proceeding
}

Try / catch

Catch Exception from the editor around token-giving and re-resolve the token list once before retrying; if the retry fails too, surface the failure instead of looping.

Prevention

When it happens

Trigger: Calling the token editor (give/award flow) with a token PHID that fails to load: a stale PHID from an old UI, a hand-built request, or a token the actor cannot see.

Common situations: Clients caching token PHIDs past their lifetime; extensions or bots posting token reactions with hardcoded PHIDs; policy changes hiding the token from the actor.

Related errors


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