{"record":{"id":"8b1416d79f458d88","repo":"phacility/phabricator","slug":"edge-search-must-specify-a-nonempty-list-of-edge-t","errorCode":null,"errorMessage":"Edge search must specify a nonempty list of edge types.","messagePattern":"Edge search must specify a nonempty list of edge types\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"src/infrastructure/edges/conduit/EdgeSearchConduitAPIMethod.php","lineNumber":98,"sourceCode":"    $object_query = id(new PhabricatorObjectQuery())\n      ->setViewer($viewer)\n      ->withNames($source_phids);\n\n    $object_query->execute();\n    $objects = $object_query->getNamedResults();\n    foreach ($source_phids as $phid) {\n      if (empty($objects[$phid])) {\n        throw new Exception(\n          pht(\n            'Source PHID \"%s\" does not identify a valid object, or you do '.\n            'not have permission to view it.',\n            $phid));\n      }\n    }\n    $source_phids = mpull($objects, 'getPHID');\n\n    if (!$edge_types) {\n      throw new Exception(\n        pht(\n          'Edge search must specify a nonempty list of edge types.'));\n    }\n\n    $edge_map = $this->getConduitEdgeTypeMap();\n\n    $constant_map = array();\n    $edge_constants = array();\n    foreach ($edge_types as $edge_type) {\n      if (!isset($edge_map[$edge_type])) {\n        throw new Exception(\n          pht(\n            'Edge type \"%s\" is not a recognized edge type.',\n            $edge_type));\n      }\n\n      $constant = $edge_map[$edge_type]->getEdgeConstant();\n","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/edges/conduit/EdgeSearchConduitAPIMethod.php#L80-L116","documentation":"Thrown by `edge.search` when the `types` parameter is missing, empty, or not a list of strings. Edge types constrain which relationships the query traverses (e.g. `task.project`, `revision.reviewers`); there is no 'all edges' mode over Conduit because the edge table mixes dozens of relation types, so a nonempty list is mandatory before the type map lookup.","triggerScenarios":"`edge.search` with only `sourcePHIDs` and no `types`; `'types' => array()`; passing `null` or a scalar where the list is expected; Python/JS clients omitting the key entirely because it looks optional.","commonSituations":"Copy-paste Conduit call templates where the types line was dropped; dynamically built parameter dicts whose types array conditionally ends up empty; misunderstanding that destinationPHIDs alone does not imply the edge type.","solutions":["Supply at least one recognized edge type key: `'types' => array('task.project')`","Discover valid keys by calling `edge.search` with no arguments — the method returns the table of conduit keys, names, and inverses"],"exampleFix":"// before\n$client->callMethod('edge.search', array(\n  'sourcePHIDs' => array('PHID-PROJ-xyz'),\n));\n\n// after\n$client->callMethod('edge.search', array(\n  'sourcePHIDs' => array('PHID-PROJ-xyz'),\n  'types' => array('task.project'),\n));","handlingStrategy":"validation","validationCode":"if (empty($params['types']) || !is_array($params['types'])) {\n  throw new InvalidArgumentException(\n    'edge.search requires a nonempty types list, e.g. array(\"task.project\")');\n}\n$result = $client->callMethod('edge.search', $params);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make the types list a required key in your conduit call builders","Fetch the valid key table once (edge.search with no args) and assert your configured keys against it at startup"],"tags":["phabricator","conduit","api","edges","missing-required-parameter"],"backgroundTag":"missing-required-parameter","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}