{"record":{"id":"eafb18e23a76e689","repo":"phacility/phabricator","slug":"calls-to-transaction-search-must-specify-either","errorCode":null,"errorMessage":"Calls to \"transaction.search\" must specify either an \"objectType\" or an \"objectIdentifier\"","messagePattern":"Calls to \"transaction\\.search\" must specify either an \"objectType\" or an \"objectIdentifier\"","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php","lineNumber":366,"sourceCode":"      );\n    }\n\n    return array(\n      'operations' => $operations,\n    );\n  }\n\n  private function loadTemplateObject(ConduitAPIRequest $request) {\n    $viewer = $request->getUser();\n\n    $object_identifier = $request->getValue('objectIdentifier');\n    $object_type = $request->getValue('objectType');\n\n    $has_identifier = ($object_identifier !== null);\n    $has_type = ($object_type !== null);\n\n    if (!$has_type && !$has_identifier) {\n      throw new Exception(\n        pht(\n          'Calls to \"transaction.search\" must specify either an \"objectType\" '.\n          'or an \"objectIdentifier\"'));\n    } else if ($has_type && $has_identifier) {\n      throw new Exception(\n        pht(\n          'Calls to \"transaction.search\" must not specify both an '.\n          '\"objectType\" and an \"objectIdentifier\".'));\n    }\n\n    if ($has_type) {\n      $all_types = PhabricatorPHIDType::getAllTypes();\n\n      if (!isset($all_types[$object_type])) {\n        ksort($all_types);\n        throw new Exception(\n          pht(\n            'In call to \"transaction.search\", specified \"objectType\" (\"%s\") '.","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php#L348-L384","documentation":"transaction.search must know which application's transactions to load, either by object type (objectType, a PHID type constant) or by a concrete object (objectIdentifier used to load a template object). With both values null, the method cannot pick a query template and throws this Exception before any querying. Exactly one of the two keys must be present.","triggerScenarios":"A conduit call carrying only pagination keys (limit, after, before) with neither objectType nor objectIdentifier; a client that defaults both to null and sends them anyway.","commonSituations":"Client wrappers building the parameter dict from optional variables that are all unset; integrations copied from a minimal example that assumed a default object type.","solutions":["Pass objectType (a PHID type constant like TASK) to search transactions across objects of that type.","Or pass objectIdentifier (e.g. 'T123', a monogram, or a raw PHID) to scope to one object.","Assert exactly one of the two keys is set before sending the request."],"exampleFix":"# before\n{\"limit\": 100}\n# after\n{\"objectType\": \"TASK\", \"limit\": 100}","handlingStrategy":"validation","validationCode":"// require exactly one selector before calling transaction.search\n$has_type = ($object_type !== null);\n$has_id = ($object_identifier !== null);\nif ($has_type === $has_id) {\n  throw new InvalidArgumentException(\n    'Pass exactly one of objectType or objectIdentifier.');\n}","typeGuard":"// PHP\nfunction hasValidSelector($object_type, $object_identifier) {\n  return (($object_type !== null) xor ($object_identifier !== null));\n}","tryCatchPattern":"Catch the conduit error client-side, match 'must specify either', and abort with a programmer-facing message — this is a client bug, not transient state.","preventionTips":["Build the selector exactly once in client code instead of merging defaults.","Fail fast in client wrappers when neither selector is set."],"tags":["phabricator","conduit","transaction-search","api"],"backgroundTag":"api-parameter-validation","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}