{"record":{"id":"8e38191db2130ca3","repo":"phacility/phabricator","slug":"image-s-belongs-to-the-wrong-object-s-ex","errorCode":null,"errorMessage":"Image (\"%s\") belongs to the wrong object (\"%s\", expected \"%s\").","messagePattern":"Image \\(\"(.+?)\"\\) belongs to the wrong object \\(\"(.+?)\", expected \"(.+?)\"\\)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/pholio/editor/PholioMockEditor.php","lineNumber":229,"sourceCode":"  public function loadPholioImage($object, $phid) {\n    if (!isset($this->images[$phid])) {\n\n      $image = id(new PholioImageQuery())\n        ->setViewer($this->getActor())\n        ->withPHIDs(array($phid))\n        ->executeOne();\n\n      if (!$image) {\n        throw new Exception(\n          pht(\n            'No image exists with PHID \"%s\".',\n            $phid));\n      }\n\n      $mock_phid = $image->getMockPHID();\n      if ($mock_phid) {\n        if ($mock_phid !== $object->getPHID()) {\n          throw new Exception(\n            pht(\n              'Image (\"%s\") belongs to the wrong object (\"%s\", expected \"%s\").',\n              $phid,\n              $mock_phid,\n              $object->getPHID()));\n        }\n      }\n\n      $this->images[$phid] = $image;\n    }\n\n    return $this->images[$phid];\n  }\n\n}\n","sourceCodeStart":211,"sourceCodeEnd":245,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/pholio/editor/PholioMockEditor.php#L211-L245","documentation":"loadPholioImage found the image, but its mockPHID does not match the mock being edited - the transaction tried to operate on an image owned by a different mock. The editor throws immediately to prevent cross-object mutation (e.g. deleting or replacing another mock's image through this edit).","triggerScenarios":"A replaceImage transaction carries a PHID from mock B while editing mock A; client code building transactions from a global image list instead of the mock's own images; duplicated seed data where the same image PHID appears in two mocks.","commonSituations":"Copy-pasted transaction templates between mocks; caching layers that mix image sets across mocks; hand-written API clients ignoring mock scoping.","solutions":["Use only image PHIDs returned by PholioImageQuery->withMockPHIDs(array($current_mock_phid))","Reload the mock and rebuild the transaction list from its actual images","Audit client code for image PHIDs sourced outside the mock being edited"],"exampleFix":"// before\n$image = id(new PholioImageQuery())->withPHIDs(array($any_phid))->executeOne();\n// after\n$image = id(new PholioImageQuery())\n  ->withPHIDs(array($phid))\n  ->withMockPHIDs(array($object->getPHID()))\n  ->executeOne();","handlingStrategy":"validation","validationCode":"// Enforce mock ownership before queuing a transaction\nif ($image->getMockPHID() && $image->getMockPHID() !== $mock->getPHID()) {\n  throw new Exception('Image belongs to a different mock.');\n}","typeGuard":"function imageBelongsToMock(PholioImage $image, PholioMock $mock) {\n  $owner = $image->getMockPHID();\n  return $owner === null || $owner === $mock->getPHID();\n}","tryCatchPattern":null,"preventionTips":["Scope every image query with withMockPHIDs() to the mock being edited","Do not source image PHIDs from global lists or other mocks","Rebuild transaction payloads from freshly loaded mock images"],"tags":["phabricator","pholio","mock","image","ownership"],"backgroundTag":"object-ownership-mismatch","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}