{"record":{"id":"671d8691988cfba2","repo":"phacility/phabricator","slug":"this-object-s-has-more-than-s-transactions-i","errorCode":null,"errorMessage":"This object (\"%s\") has more than %s transactions in its most recent transaction group; this is too many.","messagePattern":"This object \\(\"(.+?)\"\\) has more than (.+?) transactions in its most recent transaction group; this is too many\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/herald/controller/HeraldTestConsoleController.php","lineNumber":308,"sourceCode":"        if ($recent_id === null) {\n          // If the first transaction has no group ID, it is likely an older\n          // transaction from before the introduction of group IDs. In this\n          // case, select only the most recent transaction and bail out.\n          $applied[] = $xaction;\n          break;\n        }\n      }\n\n      // If this transaction is from a different transaction group, we've\n      // found all the transactions applied in the most recent group.\n      if ($group_id !== $recent_id) {\n        break;\n      }\n\n      $applied[] = $xaction;\n\n      if (count($applied) > $hard_limit) {\n        throw new Exception(\n          pht(\n            'This object (\"%s\") has more than %s transactions in its most '.\n            'recent transaction group; this is too many.',\n            $object->getPHID(),\n            new PhutilNumber($hard_limit)));\n      }\n    }\n\n    return $applied;\n\n  }\n\n}\n","sourceCodeStart":290,"sourceCodeEnd":322,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/herald/controller/HeraldTestConsoleController.php#L290-L322","documentation":"Thrown by HeraldTestConsoleController::loadAppliedTransactions() while building a dry-run test in the Herald test console. It walks the object's transactions (skipping Herald-applied ones) grouped by transaction group ID, and hard-caps the most recent group at $hard_limit = 1000. If a single transaction group exceeds 1000 entries, iteration is aborted with this exception naming the object PHID and the limit.","triggerScenarios":"Opening /herald/test/ for an object (e.g. a Maniphest task or revision) whose most recent transaction group contains more than 1000 transactions — typically produced by a bulk editor (batch edit of thousands of subtasks), a runaway script, or an import that created a huge single-group edit.","commonSituations":"Bulk-modifying thousands of objects that all transaction onto one parent; a loop in custom code applying transactions one-by-one within the same group; data imports replayed as a single grouped edit. The test console is a diagnostic page, so this surfaces exactly when admins try to dry-run rules against pathological objects.","solutions":["Pick a healthier object of the same type for the dry run — the limit protects the console from pathological groups, not the object itself.","If the object is legitimately huge, test the rules from the CLI instead: bin/herald test --object <monogram> --type <content type>, which does not load applied transactions this way.","Fix the producer: batch your edits into smaller transaction groups or fewer, larger transactions so no single group approaches 1000.","Raise the hard limit locally only if you accept the memory/time cost (edit $hard_limit in HeraldTestConsoleController), then re-run and archive/delete what you can."],"exampleFix":"// before — one transaction per object, all sharing a group id\nforeach ($phids as $phid) {\n  apply_xaction($parent, $phid, $group_id); // 1000+ entries -> error 831\n}\n\n// after — chunk the work into distinct groups\nforeach (array_chunk($phids, 100) as $chunk) {\n  apply_batch($parent, $chunk); // each batch = its own transaction group\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  $xactions = $this->loadAppliedTransactions($object);\n} catch (Exception $ex) {\n  if (strpos($ex->getMessage(), 'transactions in its most recent') !== false) {\n    // fall back to running rules without 'applied transactions' context,\n    // or direct the user to a smaller object\n  }\n}","preventionTips":["Never generate 1000+ transactions in one transaction group; chunk bulk edits into separate groups.","Prefer the CLI dry run (bin/herald test) for pathologically large objects.","Treat a single grouped edit touching thousands of subtasks as a design smell in your automation."],"tags":["herald","phabricator","php","test-console","transactions","bulk-edit","hard-limit"],"backgroundTag":"hard-limit-exceeded","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}