{"record":{"id":"611f90a47ceba0da","repo":"phacility/phabricator","slug":"constraint-authorphids-to-transaction-search-r","errorCode":null,"errorMessage":"Constraint \"authorPHIDs\" to \"transaction.search\" requires nonempty list, empty list provided.","messagePattern":"Constraint \"authorPHIDs\" to \"transaction\\.search\" requires nonempty list, empty list provided\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php","lineNumber":318,"sourceCode":"        'authorPHIDs' => 'optional list<string>',\n      ));\n\n    $with_phids = idx($constraints, 'phids');\n\n    if ($with_phids === array()) {\n      throw new Exception(\n        pht(\n          'Constraint \"phids\" to \"transaction.search\" requires nonempty list, '.\n          'empty list provided.'));\n    }\n\n    if ($with_phids) {\n      $query->withPHIDs($with_phids);\n    }\n\n    $with_authors = idx($constraints, 'authorPHIDs');\n    if ($with_authors === array()) {\n      throw new Exception(\n        pht(\n          'Constraint \"authorPHIDs\" to \"transaction.search\" requires '.\n          'nonempty list, empty list provided.'));\n    }\n\n    if ($with_authors) {\n      $query->withAuthorPHIDs($with_authors);\n    }\n\n    return $query;\n  }\n\n  private function newEdgeTransactionFields(\n    PhabricatorApplicationTransaction $xaction) {\n\n    $record = PhabricatorEdgeChangeRecord::newFromTransaction($xaction);\n\n    $operations = array();","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php#L300-L336","documentation":"Identical shape to the phids constraint: constraints.authorPHIDs is optional, but an explicitly empty array is rejected because an IN-filter over zero authors matches nothing and almost always signals a client bug. The strict `=== array()` check only fires when the key is present with an empty list; null or a nonempty list passes through to withAuthorPHIDs().","triggerScenarios":"Calling transaction.search with constraints: {\"authorPHIDs\": []} when the caller's author filter selection came out empty.","commonSituations":"Scripts that always populate authorPHIDs from a variable that can be empty; UI controllers forwarding an empty 'authors' tokenizer field.","solutions":["Only include authorPHIDs in the constraints when the list has at least one PHID.","Pass at least one author PHID when author filtering is intended.","Centralize constraint building in one helper that strips empty lists."],"exampleFix":"// before\n$params = array('constraints' => array('authorPHIDs' => $authors));\n// after\n$params = array('constraints' => array());\nif ($authors) {\n  $params['constraints']['authorPHIDs'] = $authors;\n}","handlingStrategy":"validation","validationCode":"// strip empty constraint lists before the conduit call\n$constraints = array();\nif ($author_phids) {\n  $constraints['authorPHIDs'] = $author_phids;\n}\n$parameters = array('constraints' => $constraints);","typeGuard":"// PHP: only nonempty string lists may be sent as authorPHIDs\nfunction isValidAuthorList($value) {\n  return $value === null\n    || (is_array($value) && count($value) > 0\n        && !in_array('', $value, true));\n}","tryCatchPattern":"Catch the conduit error client-side, detect 'requires nonempty list' naming authorPHIDs, and re-send once with the empty list removed.","preventionTips":["Map empty UI multi-selects to an omitted key, not an empty array.","Unit-test client serialization with empty filter inputs."],"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"}