phacility/phabricator · warning · PhutilArgumentUsageException

The specified content type ("%s") does not support dry runs.

Error message

The specified content type ("%s") does not support dry runs. Choose a testable content type. For this object, valid content types are: %s.

What it means

The --type passed to 'bin/herald test' does resolve to a real Herald adapter for the object ($display_adapters), but that adapter does not support dry runs: canCreateTestAdapterForObject($object) returned false, so it is missing from $can_select. Herald can show rules of that type but cannot execute a test adapter for it, so the command refuses and points you at the testable types.

Source

Thrown at src/applications/herald/management/HeraldTestManagementWorkflow.php:90

    if (!strlen($content_type)) {
      throw new PhutilArgumentUsageException(
        pht(
          'Specify a content type to run rules for. For this object, valid '.
          'content types are: %s.',
          implode(', ', array_keys($can_select))));
    }

    if (!isset($can_select[$content_type])) {
      if (!isset($display_adapters[$content_type])) {
        throw new PhutilArgumentUsageException(
          pht(
            'Specify a content type to run rules for. The specified content '.
            'type ("%s") is not valid. For this object, valid content types '.
            'are: %s.',
            $content_type,
            implode(', ', array_keys($can_select))));
      } else {
        throw new PhutilArgumentUsageException(
          pht(
            'The specified content type ("%s") does not support dry runs. '.
            'Choose a testable content type. For this object, valid content '.
            'types are: %s.',
            $content_type,
            implode(', ', array_keys($can_select))));
      }
    }

    $adapter = $can_select[$content_type]->newTestAdapter(
      $viewer,
      $object);

    $content_source = $this->newContentSource();

    $adapter
      ->setContentSource($content_source)
      ->setIsNewObject(false)

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Choose a content type from the valid list in the error message; those are exactly the dry-run-capable adapters for the object.
  2. If you only need to inspect rule evaluation for the non-testable type, use the web UI Herald test console instead.
  3. If you maintain a custom adapter, implement canCreateTestAdapterForObject() and newTestAdapter() to make it testable.

Example fix

// before
./bin/herald test --object X123 --type <display-only-type>
// after
./bin/herald test --object X123 --type <one of the valid types listed in the error>
Defensive patterns

Strategy: validation

Validate before calling

// Filter candidates down to dry-run-capable adapters before choosing --type:
$testable = array();
foreach (HeraldAdapter::getAllAdapters() as $key => $adapter) {
  if ($adapter->isTestAdapterForObject($object)
      && $adapter->isAvailableToUser($viewer)
      && $adapter->canCreateTestAdapterForObject($object)) {
    $testable[] = $key;
  }
}
// pick $type from $testable only

Type guard

function isDryRunnableHeraldAdapter(HeraldAdapter $adapter, $object) {
  return $adapter->canCreateTestAdapterForObject($object);
}

Prevention

When it happens

Trigger: Passing a display-only content type to 'bin/herald test', i.e. any adapter where isTestAdapterForObject() is true but canCreateTestAdapterForObject() is false for the selected object (an adapter that never implemented newTestAdapter()).

Common situations: Expecting every rule type visible in the web UI test console to be CLI-testable; custom adapters that render rules but have no test-adapter implementation; newly added adapters that only implement display.

Related errors


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