{"record":{"id":"5d26928fde542bd1","repo":"phacility/phabricator","slug":"failed-to-reload-object-identified-by-monogram-s","errorCode":null,"errorMessage":"Failed to reload object identified by monogram \"%s\" when querying by PHID.","messagePattern":"Failed to reload object identified by monogram \"(.+?)\" when querying by PHID\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/editengine/PhabricatorEditEngine.php","lineNumber":772,"sourceCode":"    $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 '.\n          'querying by PHID.',\n          $identifier));\n    }\n\n    return $object;\n  }\n\n  /**\n   * Load an object by ID.\n   *\n   * @param int Object ID.\n   * @param list<const> List of required capability constants, or omit for\n   *   defaults.\n   * @return object|null Object, or null if no such object exists.\n   * @task load\n   */","sourceCodeStart":754,"sourceCodeEnd":790,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/editengine/PhabricatorEditEngine.php#L754-L790","documentation":"After a monogram resolves to an object of the correct class, the edit engine reloads it by PHID through its own standard query (with need* clauses and policy checks). This exception means that second, authoritative load unexpectedly returned nothing even though the name lookup just succeeded.","triggerScenarios":"The object is deleted or policy-changed between the withNames() resolution and the newObjectFromPHID() reload (a narrow race); an exotic policy/flag combination where the generic name query can see an object the engine's own required-capability query cannot.","commonSituations":"Concurrent automation where one process deletes or locks the object mid-edit; objects whose edit policy was just restricted; very rare in practice — most users hit this during high-concurrency bulk editing.","solutions":["Re-check the object still exists and is editable, then retry the edit once","If it recurs deterministically for one object, compare the viewer's view vs edit policy on it and loosen policy or use a privileged viewer","Serialize bulk edits so a delete/lock cannot interleave with a reload","Treat persistent occurrences as a data/policy anomaly on that specific object and inspect it manually"],"exampleFix":"// before: single attempt that can lose the race\n$result = $client->callMethod('maniphest.edit', $parameters);\n\n// after: re-validate and retry once on this specific failure\ntry {\n  $result = $client->callMethod('maniphest.edit', $parameters);\n} catch (ConduitClientException $ex) {\n  if (strpos($ex->getMessage(), 'Failed to reload object') === false) {\n    throw $ex;\n  }\n  $still = $client->callMethod('maniphest.search', array(\n    'constraints' => array('phids' => array($phid)),\n  ));\n  if ($still['data']) {\n    $result = $client->callMethod('maniphest.edit', $parameters); // retry once\n  }\n}","handlingStrategy":"retry","validationCode":"// Before retrying, confirm the object still exists for this viewer:\n$still = $client->callMethod('maniphest.search', array(\n  'constraints' => array('phids' => array($phid)),\n));\nif (empty($still['data'])) {\n  // genuinely gone now; give up cleanly\n}","typeGuard":null,"tryCatchPattern":"try {\n  $result = $client->callMethod('maniphest.edit', $parameters);\n} catch (ConduitClientException $ex) {\n  if (strpos($ex->getMessage(), 'Failed to reload object') !== false) {\n    // transient race: re-check existence, then retry exactly once\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Retry at most once — a persistent failure means a policy/data problem, not a race","Avoid interleaving bulk deletes and bulk edits against the same object set","Log the PHID when this fires so the specific object can be inspected"],"tags":["phabricator","edit-engine","race-condition","object-not-found","conduit"],"backgroundTag":"object-not-found","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}