{"record":{"id":"e9e8340057ca4863","repo":"phacility/phabricator","slug":"calls-to-transaction-search-must-not-specify-bot","errorCode":null,"errorMessage":"Calls to \"transaction.search\" must not specify both an \"objectType\" and an \"objectIdentifier\".","messagePattern":"Calls to \"transaction\\.search\" must not specify both an \"objectType\" and an \"objectIdentifier\"\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php","lineNumber":371,"sourceCode":"    );\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\") '.\n            'is unknown. Valid object types are: %s.',\n            $object_type,\n            implode(', ', array_keys($all_types))));\n      }\n","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php#L353-L389","documentation":"objectType and objectIdentifier are mutually exclusive: the first builds a fresh template object from a PHID type, the second loads an existing object by name. Supplying both is ambiguous and rejected with this Exception. The xor check ($has_type && $has_identifier) runs before any lookup, so the conflict is caught regardless of whether the values are individually valid.","triggerScenarios":"A conduit call setting both objectType and objectIdentifier, e.g. {\"objectType\": \"TASK\", \"objectIdentifier\": \"T123\"} — typically a client that fills in every known field.","commonSituations":"Over-eager generated clients populating all optional parameters; code paths merging a 'defaults' dict with user-supplied values, ending up with both keys.","solutions":["Send exactly one of the two keys; drop the other.","Fix client merge logic so defaults do not resurrect a key the caller left unset.","When you hold a concrete object, prefer objectIdentifier alone."],"exampleFix":"# before\n{\"objectType\": \"TASK\", \"objectIdentifier\": \"T123\"}\n# after\n{\"objectIdentifier\": \"T123\"}","handlingStrategy":"validation","validationCode":"// reject both-selectors-present before calling\nif ($object_type !== null && $object_identifier !== null) {\n  throw new InvalidArgumentException(\n    'objectType and objectIdentifier are mutually exclusive.');\n}","typeGuard":"// PHP\nfunction selectorsAreExclusive($object_type, $object_identifier) {\n  return !($object_type !== null && $object_identifier !== null);\n}","tryCatchPattern":"Catch the conduit error client-side, match 'must not specify both', strip one selector, and re-send once with the preferred key.","preventionTips":["Do not merge a defaults dict over user-supplied parameters without unsetting nulls.","Prefer objectIdentifier when a concrete object is known."],"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"}