phacility/phabricator · error · Exception
Image ("%s") belongs to the wrong object ("%s", expected "%s
Error message
Image ("%s") belongs to the wrong object ("%s", expected "%s"). What it means
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).
Source
Thrown at src/applications/pholio/editor/PholioMockEditor.php:229
public function loadPholioImage($object, $phid) {
if (!isset($this->images[$phid])) {
$image = id(new PholioImageQuery())
->setViewer($this->getActor())
->withPHIDs(array($phid))
->executeOne();
if (!$image) {
throw new Exception(
pht(
'No image exists with PHID "%s".',
$phid));
}
$mock_phid = $image->getMockPHID();
if ($mock_phid) {
if ($mock_phid !== $object->getPHID()) {
throw new Exception(
pht(
'Image ("%s") belongs to the wrong object ("%s", expected "%s").',
$phid,
$mock_phid,
$object->getPHID()));
}
}
$this->images[$phid] = $image;
}
return $this->images[$phid];
}
}
View on GitHub (pinned to 5720a38cfe)
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
Example fix
// before $image = id(new PholioImageQuery())->withPHIDs(array($any_phid))->executeOne(); // after $image = id(new PholioImageQuery()) ->withPHIDs(array($phid)) ->withMockPHIDs(array($object->getPHID())) ->executeOne();
Defensive patterns
Strategy: validation
Validate before calling
// Enforce mock ownership before queuing a transaction
if ($image->getMockPHID() && $image->getMockPHID() !== $mock->getPHID()) {
throw new Exception('Image belongs to a different mock.');
} Type guard
function imageBelongsToMock(PholioImage $image, PholioMock $mock) {
$owner = $image->getMockPHID();
return $owner === null || $owner === $mock->getPHID();
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Copy-pasted transaction templates between mocks; caching layers that mix image sets across mocks; hand-written API clients ignoring mock scoping.
Related errors
- No image exists with PHID "%s".
- File is not viewable.
- Request parameter "%s" is not formatted properly. Expected a
- Request parameter "%s" is not formatted properly. Expected a
- Invalid Request (CSRF)
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/8e38191db2130ca3.
Report an issue: GitHub.