{"record":{"id":"54e36338e9b25166","repo":"phacility/phabricator","slug":"you-can-not-create-a-relationship-of-type-s-t","errorCode":null,"errorMessage":"You can not create a relationship (of type \"%s\") to object \"%s\" because it is not the right type of object for this relationship.","messagePattern":"You can not create a relationship \\(of type \"(.+?)\"\\) to object \"(.+?)\" because it is not the right type of object for this relationship\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/search/controller/PhabricatorSearchRelationshipController.php","lineNumber":102,"sourceCode":"          $dst_object = idx($dst_objects, $add_phid);\n          if (!$dst_object) {\n            throw new Exception(\n              pht(\n                'You can not create a relationship to object \"%s\" because '.\n                'the object does not exist or could not be loaded.',\n                $add_phid));\n          }\n\n          if ($add_phid == $src_phid) {\n            throw new Exception(\n              pht(\n                'You can not create a relationship to object \"%s\" because '.\n                'objects can not be related to themselves.',\n                $add_phid));\n          }\n\n          if (!$relationship->canRelateObjects($object, $dst_object)) {\n            throw new Exception(\n              pht(\n                'You can not create a relationship (of type \"%s\") to object '.\n                '\"%s\" because it is not the right type of object for this '.\n                'relationship.',\n                $relationship->getRelationshipConstant(),\n                $add_phid));\n          }\n        }\n      } catch (Exception $ex) {\n        return $this->newUnrelatableObjectResponse($ex, $done_uri);\n      }\n\n      $content_source = PhabricatorContentSource::newFromRequest($request);\n      $relationship->setContentSource($content_source);\n\n      $editor = $object->getApplicationTransactionEditor()\n        ->setActor($viewer)\n        ->setContentSource($content_source)","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/search/controller/PhabricatorSearchRelationshipController.php#L84-L120","documentation":"Each PhabricatorRelationship class implements canRelateObjects($src, $dst) to enforce type rules (e.g. 'Maniphest Task: subscribers' accepts users/projects, 'Differential Revision: depends on' accepts tasks/revisions). If an added destination object loads fine but fails that type check, this Exception names the relationship constant and the offending PHID; the controller catches it and renders the unrelatable-object response.","triggerScenarios":"POSTing a relationship with a valid but wrong-typed target: adding a Diffusion Commit as a task subscriber, adding a user as a 'depends on' task, adding a Monogram-resolved object the typeahead for that dialog should not have offered.","commonSituations":"Stale dialog after an application extension changed relationship rules in a patch; users pasting arbitrary object monograms/URLs into the tokenizer bypassing its filter; custom code or fork extensions that changed relationship targets without updating dialogs; race where object type changed (e.g. a project converted/archived).","solutions":["Pick a target of the type the dialog's typeahead offers - the autocomplete is already filtered by the relationship's allowed object types.","If scripting, validate candidate PHIDs against the relationship before POSTing: $relationship->canRelateObjects($src, $dst) is a public check you can call.","Reload the page to get current dialog configuration after upgrading or changing phabricator/extensions.","Re-read the exception: it names the relationship constant (e.g. 'maniphest.subscribers') so you know which dialog/rule rejected the pair."],"exampleFix":"// before: add whatever the user typed\n$phids = explode(';', $request->getStr('phids'));\n\n// after: filter to relatable objects before applying\n$phids = array_filter($phids, function ($phid) use ($relationship, $object, $dst_objects) {\n  $dst = idx($dst_objects, $phid);\n  return $dst && $relationship->canRelateObjects($object, $dst);\n});","handlingStrategy":"validation","validationCode":"$targets = array();\nforeach ($add_phids as $phid) {\n  $dst = idx($loadable, $phid);\n  if ($dst && $relationship->canRelateObjects($object, $dst)) {\n    $targets[] = $phid;\n  }\n}","typeGuard":"function isRelatable($relationship, $src, $dst) { return $relationship->canRelateObjects($src, $dst); }","tryCatchPattern":"try {\n  foreach ($add_phids as $add_phid) { /* ...checks... */ }\n} catch (Exception $ex) {\n  return $this->newUnrelatableObjectResponse($ex, $done_uri);\n}","preventionTips":["Use the dialog's own typeahead datasource - it is pre-filtered to relatable types","Call canRelateObjects() in scripts before batching relationship edits","Re-test custom relationship extensions against all object types after upgrades"],"tags":["phabricator","relationships","type-mismatch","validation","controller"],"backgroundTag":"relationship-type-mismatch","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}