phacility/phabricator · error · Exception

Monogram "%s" identifies an object of the wrong type. Loaded

Error message

Monogram "%s" identifies an object of the wrong type. Loaded object has class "%s", but this editor operates on objects of type "%s".

What it means

After resolving a monogram to some object, PhabricatorEditEngine::newObjectFromIdentifier() compares the loaded object's concrete class against a fresh instance from newEditableObject(). If they differ, the monogram points at an object type this particular editor cannot operate on, and this exception is thrown.

Source

Thrown at src/applications/transactions/editengine/PhabricatorEditEngine.php:756

      return $object;
    }

    $target = id(new PhabricatorObjectQuery())
      ->setViewer($this->getViewer())
      ->withNames(array($identifier))
      ->executeOne();
    if (!$target) {
      throw new Exception(
        pht(
          'Monogram "%s" does not identify a valid object.',
          $identifier));
    }

    $expect = $this->newEditableObject();
    $expect_class = get_class($expect);
    $target_class = get_class($target);
    if ($expect_class !== $target_class) {
      throw new Exception(
        pht(
          'Monogram "%s" identifies an object of the wrong type. Loaded '.
          'object has class "%s", but this editor operates on objects of '.
          'type "%s".',
          $identifier,
          $target_class,
          $expect_class));
    }

    // Load the object by PHID using this engine's standard query. This makes
    // sure it's really valid, goes through standard policy check logic, and
    // picks up any `need...()` clauses we want it to load with.

    $object = $this->newObjectFromPHID($target->getPHID(), $capabilities);
    if (!$object) {
      throw new Exception(
        pht(
          'Failed to reload object identified by monogram "%s" when '.

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Route by object type: resolve the monogram (phid.lookup) and dispatch to the *.edit method matching its PHID type (TASK -> maniphest.edit, DREV -> differential.revision.edit)
  2. Pass the correct monogram/ID for the editor you are invoking
  3. Use the generic editing pipeline only after confirming get_class matches, or use the object's own edit engine
  4. Catch the exception and surface 'wrong object type for this editor' to the operator

Example fix

// before: differential monogram sent to the task editor
$parameters = array('objectIdentifier' => 'D18', 'transactions' => $transactions);
$result = $client->callMethod('maniphest.edit', $parameters);
// Exception: Monogram "D18" identifies an object of the wrong type ...

// after: dispatch on the resolved PHID type
$lookup = $client->callMethod('phid.lookup', array('names' => array('D18')));
$type = substr(idx(idx($lookup, 'D18', array()), 'type', ''), 0, 4);
$method = array('TASK' => 'maniphest.edit', 'DREV' => 'differential.revision.edit')[$type] ?? null;
if ($method === null) {
  // unsupported object type; do not call an edit engine with it
}
$result = $client->callMethod($method, $parameters);
Defensive patterns

Strategy: type-guard

Validate before calling

// Dispatch to the editor matching the resolved object type:
$lookup = $client->callMethod('phid.lookup', array('names' => array($monogram)));
$info = idx($lookup, $monogram);
if ($info === null) { /* unknown monogram */ }
$type = idx($info, 'type'); // e.g. 'TASK', 'DREV'
$method = array(
  'TASK' => 'maniphest.edit',
  'DREV' => 'differential.revision.edit',
  'PROJ' => 'project.edit',
)[$type] ?? null;
if ($method === null) { /* unsupported type; stop */ }

Type guard

function editorSupportsObjectType($phid_type, array $supported) {
  return in_array($phid_type, $supported, true);
}

Try / catch

try {
  $result = $client->callMethod($method, $parameters);
} catch (ConduitClientException $ex) {
  if (strpos($ex->getMessage(), 'identifies an object of the wrong type') !== false) {
    // your routing picked the wrong editor; re-dispatch by PHID type
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Passing a monogram of the wrong product to an editor, e.g. objectIdentifier="D18" (a Differential revision) to maniphest.edit, or "T18" to differential.revision.edit; passing a project monogram "P5" to a task editor.

Common situations: Automation that edits whichever object a URL/field contains without checking its type first; copy-paste of monograms between tools; generic edit scripts shared across object types that hardcode one *.edit method.

Related errors


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