phacility/phabricator · error · PhutilArgumentUsageException

OAuth client " " is already trusted.

Error message

OAuth client "%s" is already trusted.

What it means

Thrown by `bin/auth trust-oauth-client` when the requested OAuth client already has its isTrusted flag set. The workflow explicitly refuses to be a no-op: after loading the client it checks getIsTrusted() and aborts with this PhutilArgumentUsageException before calling setIsTrusted(1) and save(). The state of the database is unchanged.

Solutions

  1. Check the current state first: if the command says the client is already trusted, no action is needed — the desired state is already in effect.
  2. Make idempotent scripts check state before acting (query PhabricatorOAuthServerClient or run `bin/auth trust-oauth-client` and treat this exception as success).
  3. If you expected the client to be untrusted, confirm you used the right `--id` (a different client with the same name may be the one you meant).
  4. To deliberately revert to untrusted, use `bin/auth untrust-oauth-client --id N` instead.

Example fix

// before
$ bin/auth trust-oauth-client --id 7   # already run before
OAuth client "wiki-frontend" is already trusted.

// after — idempotent wrapper
$ bin/auth trust-oauth-client --id 7 2>/dev/null \
    || echo "client already trusted or not found; nothing to do"
Defensive patterns

Strategy: validation

Validate before calling

if ($client->getIsTrusted()) {
  // already in the desired state: skip the trust command entirely
} else {
  // safe to run: bin/auth trust-oauth-client --id <id>
}

Try / catch

try {
  // run trust-oauth-client
} catch (PhutilArgumentUsageException $ex) {
  if (strpos($ex->getMessage(), 'already trusted') !== false) {
    // treat as success — desired state already reached
  }
}

Prevention

When it happens

Trigger: Running `bin/auth trust-oauth-client --id N` a second time for a client that was already trusted, or against a client that was marked trusted through the web UI previously.

Common situations: An automation script re-runs the trust command on every deploy; two admins trust the same client concurrently; the admin forgot the command had already succeeded earlier.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/applications/auth/management/PhabricatorAuthManagementTrustOAuthClientWorkflow.php:46

    if (!$id) {
      throw new PhutilArgumentUsageException(
        pht(
          'Specify an OAuth client id with "--id".'));
    }

    $client = id(new PhabricatorOAuthServerClientQuery())
      ->setViewer($this->getViewer())
      ->withIDs(array($id))
      ->executeOne();

    if (!$client) {
      throw new PhutilArgumentUsageException(
        pht(
          'Failed to find an OAuth client with id %s.', $id));
    }

    if ($client->getIsTrusted()) {
      throw new PhutilArgumentUsageException(
        pht(
          'OAuth client "%s" is already trusted.',
          $client->getName()));
    }

    $client->setIsTrusted(1);
    $client->save();

    $console = PhutilConsole::getConsole();
    $console->writeOut(
      "%s\n",
      pht(
        'OAuth client "%s" is now trusted.',
        $client->getName()));
  }

}

View on GitHub (pinned to 5720a38cfe)