phacility/phabricator · error · Exception

Unknown revision status filter constant "%s".

Error message

Unknown revision status filter constant "%s".

What it means

DifferentialLegacyQuery::getModernValues() translates legacy status filter constants (STATUS_ANY, STATUS_OPEN, STATUS_ACCEPTED, and so on) into modern status lists for the query engine. Any value that is not a key of the legacy map throws. differential.query feeds its status parameter straight into this method.

Source

Thrown at src/applications/differential/constants/DifferentialLegacyQuery.php:25

  const STATUS_OPEN           = 'status-open';
  const STATUS_ACCEPTED       = 'status-accepted';
  const STATUS_NEEDS_REVIEW   = 'status-needs-review';
  const STATUS_NEEDS_REVISION = 'status-needs-revision';
  const STATUS_CLOSED         = 'status-closed';
  const STATUS_ABANDONED      = 'status-abandoned';

  public static function getAllConstants() {
    return array_keys(self::getMap());
  }

  public static function getModernValues($status) {
    if ($status === self::STATUS_ANY) {
      return null;
    }

    $map = self::getMap();
    if (!isset($map[$status])) {
      throw new Exception(
        pht(
          'Unknown revision status filter constant "%s".',
          $status));
    }

    return $map[$status];
  }

  private static function getMap() {
    $all = array_keys(DifferentialRevisionStatus::getAll());

    $open = array();
    $closed = array();

    foreach ($all as $status) {
      $status_object = DifferentialRevisionStatus::newForStatus($status);
      if ($status_object->isClosedStatus()) {
        $closed[] = $status_object->getKey();

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Use the legacy constants differential.query documents — 'status-any', 'status-open', 'status-accepted', and so on — or DifferentialLegacyQuery::getAllConstants().
  2. Omit status (or send it empty) to match all revisions and filter client-side.
  3. Migrate to differential.revision.search, which accepts modern status values.

Example fix

// before
$params['status'] = 'open';
$client->callMethodSynchronous('differential.query', $params);

// after
$params['status'] = 'status-open';
$client->callMethodSynchronous('differential.query', $params);
Defensive patterns

Strategy: validation

Validate before calling

$legacy_statuses = DifferentialLegacyQuery::getAllConstants(); // or a literal list
if ($status !== null && $status !== '' &&
    !in_array($status, $legacy_statuses, true)) {
  throw new InvalidArgumentException(
    'Unknown legacy status filter: '.$status);
}

Type guard

function isLegacyStatus($value, array $allowed) {
  return $value === null || $value === '' || in_array($value, $allowed, true);
}

Try / catch

try {
  $revisions = $client->callMethodSynchronous('differential.query', $params);
} catch (Exception $ex) {
  if (strpos($ex->getMessage(), 'status filter constant') !== false) {
    // fix the status constant or drop the status parameter and filter client-side
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Calling differential.query with a status string that is not a legacy constant — misspellings, modern status names, or invented values such as 'open' instead of 'status-open'.

Common situations: Scripts written against the modern search API whose status values leak into legacy calls; typo'd constants; old integrations after new statuses were added that never received legacy names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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