phacility/phabricator · error · Exception

Monogram " " 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.

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.

Appendix: 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)