{"record":{"id":"4651ca710a66f26e","repo":"phacility/phabricator","slug":"monogram-s-identifies-an-object-of-the-wrong-ty","errorCode":null,"errorMessage":"Monogram \"%s\" identifies an object of the wrong type. Loaded object has class \"%s\", but this editor operates on objects of type \"%s\".","messagePattern":"Monogram \"(.+?)\" identifies an object of the wrong type\\. Loaded object has class \"(.+?)\", but this editor operates on objects of type \"(.+?)\"\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/editengine/PhabricatorEditEngine.php","lineNumber":756,"sourceCode":"      return $object;\n    }\n\n    $target = id(new PhabricatorObjectQuery())\n      ->setViewer($this->getViewer())\n      ->withNames(array($identifier))\n      ->executeOne();\n    if (!$target) {\n      throw new Exception(\n        pht(\n          'Monogram \"%s\" does not identify a valid object.',\n          $identifier));\n    }\n\n    $expect = $this->newEditableObject();\n    $expect_class = get_class($expect);\n    $target_class = get_class($target);\n    if ($expect_class !== $target_class) {\n      throw new Exception(\n        pht(\n          'Monogram \"%s\" identifies an object of the wrong type. Loaded '.\n          'object has class \"%s\", but this editor operates on objects of '.\n          'type \"%s\".',\n          $identifier,\n          $target_class,\n          $expect_class));\n    }\n\n    // Load the object by PHID using this engine's standard query. This makes\n    // sure it's really valid, goes through standard policy check logic, and\n    // picks up any `need...()` clauses we want it to load with.\n\n    $object = $this->newObjectFromPHID($target->getPHID(), $capabilities);\n    if (!$object) {\n      throw new Exception(\n        pht(\n          'Failed to reload object identified by monogram \"%s\" when '.","sourceCodeStart":738,"sourceCodeEnd":774,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/editengine/PhabricatorEditEngine.php#L738-L774","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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)","Pass the correct monogram/ID for the editor you are invoking","Use the generic editing pipeline only after confirming get_class matches, or use the object's own edit engine","Catch the exception and surface 'wrong object type for this editor' to the operator"],"exampleFix":"// before: differential monogram sent to the task editor\n$parameters = array('objectIdentifier' => 'D18', 'transactions' => $transactions);\n$result = $client->callMethod('maniphest.edit', $parameters);\n// Exception: Monogram \"D18\" identifies an object of the wrong type ...\n\n// after: dispatch on the resolved PHID type\n$lookup = $client->callMethod('phid.lookup', array('names' => array('D18')));\n$type = substr(idx(idx($lookup, 'D18', array()), 'type', ''), 0, 4);\n$method = array('TASK' => 'maniphest.edit', 'DREV' => 'differential.revision.edit')[$type] ?? null;\nif ($method === null) {\n  // unsupported object type; do not call an edit engine with it\n}\n$result = $client->callMethod($method, $parameters);","handlingStrategy":"type-guard","validationCode":"// Dispatch to the editor matching the resolved object type:\n$lookup = $client->callMethod('phid.lookup', array('names' => array($monogram)));\n$info = idx($lookup, $monogram);\nif ($info === null) { /* unknown monogram */ }\n$type = idx($info, 'type'); // e.g. 'TASK', 'DREV'\n$method = array(\n  'TASK' => 'maniphest.edit',\n  'DREV' => 'differential.revision.edit',\n  'PROJ' => 'project.edit',\n)[$type] ?? null;\nif ($method === null) { /* unsupported type; stop */ }","typeGuard":"function editorSupportsObjectType($phid_type, array $supported) {\n  return in_array($phid_type, $supported, true);\n}","tryCatchPattern":"try {\n  $result = $client->callMethod($method, $parameters);\n} catch (ConduitClientException $ex) {\n  if (strpos($ex->getMessage(), 'identifies an object of the wrong type') !== false) {\n    // your routing picked the wrong editor; re-dispatch by PHID type\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Never feed arbitrary object references into a hardcoded *.edit method","Route edits by the PHID type returned from phid.lookup/phid.query","In shared edit helpers, make the expected object class an explicit parameter"],"tags":["phabricator","edit-engine","type-mismatch","monogram","conduit"],"backgroundTag":"wrong-object-type","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}