{"record":{"id":"d2913605632f9609","repo":"FuelLabs/fuel-core","slug":"the-transaction-estimation-requires-running-of-pre","errorCode":null,"errorMessage":"The transaction estimation requires running of predicate more than {} times","messagePattern":"The transaction estimation requires running of predicate more than (.+?) times","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fuel-core/src/schema/tx/assemble_tx.rs","lineNumber":666,"sourceCode":"    fn adjust_witness_limit(&mut self) {\n        // If the user sets the `WitnessLimit` policy, we are only allowed to increase\n        // it in the case if the transaction got more witnesses when we inserted new inputs.\n        let mut witness_size = self.tx.witnesses().size_dynamic() as u64;\n        witness_size = witness_size.max(self.original_witness_limit);\n        self.tx.set_witness_limit(witness_size);\n    }\n\n    async fn estimate_predicates(mut self) -> anyhow::Result<Self> {\n        if !self.arguments.estimate_predicates {\n            return Ok(self)\n        }\n\n        if !self.has_predicates {\n            return Ok(self)\n        }\n\n        if self.estimated_predicates_count >= self.arguments.estimate_predicates_limit {\n            return Err(anyhow::anyhow!(\n                \"The transaction estimation requires running \\\n                of predicate more than {} times\",\n                self.arguments.estimate_predicates_limit\n            ));\n        }\n\n        let memory = self.arguments.shared_memory_pool.get_memory().await;\n        let chain_id = self.arguments.consensus_parameters.chain_id();\n        self.tx\n            .precompute(&chain_id)\n            .map_err(|err| anyhow::anyhow!(\"{:?}\", err))?;\n\n        let parameters =\n            CheckPredicateParams::from(self.arguments.consensus_parameters.as_ref());\n        let read_view = self.arguments.read_view.clone();\n\n        let mut tx_to_estimate = self.tx;\n        let estimated_tx = tokio_rayon::spawn_fifo(move || {","sourceCodeStart":648,"sourceCodeEnd":684,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/schema/tx/assemble_tx.rs#L648-L684","documentation":"When estimatePredicates is true, the assembler runs predicate estimation; every time new inputs are added (e.g. coins to cover the fee) predicates consuming gas must be re-estimated. The node caps the number of estimation rounds at GraphQL config assemble_tx_estimate_predicates_limit (default 5, set in service/config.rs) and errors when assembly would need more rounds.","triggerScenarios":"assembleTransaction with estimatePredicates: true on a tx where the fee-covering loop keeps adding coins, each addition triggering another predicate re-estimation, exceeding the configured round limit (5 by default).","commonSituations":"Predicate-based accounts with dusty base-asset coins (many add-then-re-estimate rounds); high gas price forcing several coin-fetch iterations; node operators who lowered the limit (fuel-core sets 1 in some test configs).","solutions":["Consolidate the fee-paying account's coins so one round of coin addition suffices","Run a node with a higher --assemble-tx-estimate-predicates-limit (GraphQL config) if you control it","Avoid enabling estimatePredicates when the tx's predicates have fixed gas usage, or pre-fund the account so fewer fee rounds are needed"],"exampleFix":"# before (node config)\n# default: assemble_tx_estimate_predicates_limit = 5, tx keeps failing\n\n# after (fuel-core node TOML)\n[graphql]\nassemble_tx_estimate_predicates_limit = 20","handlingStrategy":"retry","validationCode":"// client-side: know the node's limit and the wallet's fragmentation before enabling estimation\nconst rounds = estimateFeeRounds(feeAccountCoins, estimatedFee); // coins needed / coins per round\nif (estimatePredicates && rounds > NODE_ESTIMATE_PREDICATES_LIMIT /* default 5 */) {\n  throw new Error('consolidate coins or raise assemble_tx_estimate_predicates_limit');\n}","typeGuard":null,"tryCatchPattern":"catch (e) { if (/running of predicate more than/.test(e.message)) { /* consolidate the predicate account's coins; if you run the node raise assemble_tx_estimate_predicates_limit; retry once */ } else throw e; }","preventionTips":["Keep the fee-paying account consolidated so one coin-fetch round suffices","Node operators: size assemble_tx_estimate_predicates_limit to real wallet fragmentation (default 5)","Only enable estimatePredicates when the tx actually contains predicates"],"tags":["transaction","predicate","estimation","config","assemble-tx"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}