@@ -162,8 +162,11 @@ const resolveDeferredRedeemers = (
162162 const utxo = refToUtxo . get ( key )
163163
164164 if ( index === undefined || ! utxo ) {
165- yield * Effect . logWarning ( `[Evaluation] Could not resolve self redeemer for ${ key } - UTxO not in transaction` )
166- continue
165+ return yield * Effect . fail (
166+ new TransactionBuilderError ( {
167+ message : `Self redeemer for ${ key } could not be resolved: UTxO is not present in the transaction inputs`
168+ } )
169+ )
167170 }
168171
169172 const indexedInput : IndexedInput = { index, utxo }
@@ -196,8 +199,11 @@ const resolveDeferredRedeemers = (
196199 }
197200
198201 if ( batchInputs . length === 0 ) {
199- yield * Effect . logWarning ( `[Evaluation] Batch redeemer for ${ key } has no resolved inputs` )
200- continue
202+ return yield * Effect . fail (
203+ new TransactionBuilderError ( {
204+ message : `Batch redeemer for ${ key } has no resolved inputs: none of the specified UTxOs are present in the transaction`
205+ } )
206+ )
201207 }
202208
203209 // Sort by index for consistent ordering
@@ -559,10 +565,11 @@ export const executeEvaluation = (): Effect.Effect<
559565 // For spend redeemers, map input index to UTxO reference
560566 const utxoRef = inputIndexMapping . get ( evalRedeemer . redeemer_index )
561567 if ( ! utxoRef ) {
562- yield * Effect . logWarning (
563- `[Evaluation] Could not map input index ${ evalRedeemer . redeemer_index } to UTxO reference`
568+ return yield * Effect . fail (
569+ new TransactionBuilderError ( {
570+ message : `Evaluator returned spend result at index ${ evalRedeemer . redeemer_index } but no UTxO exists at that position in the transaction`
571+ } )
564572 )
565- continue
566573 }
567574
568575 const redeemer = evaluatedRedeemers . get ( utxoRef )
@@ -578,14 +585,21 @@ export const executeEvaluation = (): Effect.Effect<
578585 `mem=${ evalRedeemer . ex_units . mem } , steps=${ evalRedeemer . ex_units . steps } `
579586 )
580587 } else {
581- yield * Effect . logWarning ( `[Evaluation] No redeemer found in state for UTxO ${ utxoRef } ` )
588+ return yield * Effect . fail (
589+ new TransactionBuilderError ( {
590+ message : `Evaluator returned spend result for ${ utxoRef } but no redeemer exists in builder state for that UTxO`
591+ } )
592+ )
582593 }
583594 } else if ( evalRedeemer . redeemer_tag === "mint" ) {
584595 // For mint redeemers, map mint index to policy ID hex
585596 const policyIdHex = mintIndexMapping . get ( evalRedeemer . redeemer_index )
586597 if ( ! policyIdHex ) {
587- yield * Effect . logWarning ( `[Evaluation] Could not map mint index ${ evalRedeemer . redeemer_index } to policy ID` )
588- continue
598+ return yield * Effect . fail (
599+ new TransactionBuilderError ( {
600+ message : `Evaluator returned mint result at index ${ evalRedeemer . redeemer_index } but no policy exists at that position in the transaction`
601+ } )
602+ )
589603 }
590604
591605 const redeemer = evaluatedRedeemers . get ( policyIdHex )
@@ -601,14 +615,21 @@ export const executeEvaluation = (): Effect.Effect<
601615 `mem=${ evalRedeemer . ex_units . mem } , steps=${ evalRedeemer . ex_units . steps } `
602616 )
603617 } else {
604- yield * Effect . logWarning ( `[Evaluation] No redeemer found in state for policy ${ policyIdHex } ` )
618+ return yield * Effect . fail (
619+ new TransactionBuilderError ( {
620+ message : `Evaluator returned mint result for policy ${ policyIdHex } but no redeemer exists in builder state for that policy`
621+ } )
622+ )
605623 }
606624 } else if ( evalRedeemer . redeemer_tag === "cert" ) {
607625 // For certificate redeemers, map index to credential key
608626 const certKey = certIndexMapping . get ( evalRedeemer . redeemer_index )
609627 if ( ! certKey ) {
610- yield * Effect . logWarning ( `[Evaluation] Could not map cert index ${ evalRedeemer . redeemer_index } to credential` )
611- continue
628+ return yield * Effect . fail (
629+ new TransactionBuilderError ( {
630+ message : `Evaluator returned cert result at index ${ evalRedeemer . redeemer_index } but no certificate exists at that position in the transaction`
631+ } )
632+ )
612633 }
613634
614635 const redeemer = evaluatedRedeemers . get ( certKey )
@@ -624,16 +645,21 @@ export const executeEvaluation = (): Effect.Effect<
624645 `mem=${ evalRedeemer . ex_units . mem } , steps=${ evalRedeemer . ex_units . steps } `
625646 )
626647 } else {
627- yield * Effect . logWarning ( `[Evaluation] No redeemer found in state for cert ${ certKey } ` )
648+ return yield * Effect . fail (
649+ new TransactionBuilderError ( {
650+ message : `Evaluator returned cert result for ${ certKey } but no redeemer exists in builder state for that credential`
651+ } )
652+ )
628653 }
629654 } else if ( evalRedeemer . redeemer_tag === "reward" ) {
630655 // For withdrawal redeemers, map index to credential key
631656 const rewardKey = withdrawalIndexMapping . get ( evalRedeemer . redeemer_index )
632657 if ( ! rewardKey ) {
633- yield * Effect . logWarning (
634- `[Evaluation] Could not map withdrawal index ${ evalRedeemer . redeemer_index } to credential`
658+ return yield * Effect . fail (
659+ new TransactionBuilderError ( {
660+ message : `Evaluator returned reward result at index ${ evalRedeemer . redeemer_index } but no withdrawal exists at that position in the transaction`
661+ } )
635662 )
636- continue
637663 }
638664
639665 const redeemer = evaluatedRedeemers . get ( rewardKey )
@@ -649,14 +675,21 @@ export const executeEvaluation = (): Effect.Effect<
649675 `mem=${ evalRedeemer . ex_units . mem } , steps=${ evalRedeemer . ex_units . steps } `
650676 )
651677 } else {
652- yield * Effect . logWarning ( `[Evaluation] No redeemer found in state for withdrawal ${ rewardKey } ` )
678+ return yield * Effect . fail (
679+ new TransactionBuilderError ( {
680+ message : `Evaluator returned reward result for ${ rewardKey } but no redeemer exists in builder state for that withdrawal`
681+ } )
682+ )
653683 }
654684 } else if ( evalRedeemer . redeemer_tag === "vote" ) {
655685 // For vote redeemers, map index to voter key
656686 const voterKey = voteIndexMapping . get ( evalRedeemer . redeemer_index )
657687 if ( ! voterKey ) {
658- yield * Effect . logWarning ( `[Evaluation] Could not map vote index ${ evalRedeemer . redeemer_index } to voter` )
659- continue
688+ return yield * Effect . fail (
689+ new TransactionBuilderError ( {
690+ message : `Evaluator returned vote result at index ${ evalRedeemer . redeemer_index } but no voter exists at that position in the transaction`
691+ } )
692+ )
660693 }
661694
662695 const redeemer = evaluatedRedeemers . get ( voterKey )
@@ -675,12 +708,20 @@ export const executeEvaluation = (): Effect.Effect<
675708 `mem=${ evalRedeemer . ex_units . mem } , steps=${ evalRedeemer . ex_units . steps } `
676709 )
677710 } else {
678- yield * Effect . logWarning ( `[Evaluation] No redeemer found in state for vote ${ voterKey } ` )
711+ return yield * Effect . fail (
712+ new TransactionBuilderError ( {
713+ message : `Evaluator returned vote result for ${ voterKey } but no redeemer exists in builder state for that voter`
714+ } )
715+ )
679716 }
680717 } else {
681- // Unknown redeemer type
682- yield * Effect . logWarning (
683- `[Evaluation] Unknown redeemer type ${ evalRedeemer . redeemer_tag } not yet supported for matching`
718+ // Unknown redeemer type returned by the evaluator — fail immediately.
719+ // Silently ignoring this would leave the redeemer at exUnits = 0, which
720+ // looks "unevaluated" to Balance and triggers an infinite retry loop.
721+ return yield * Effect . fail (
722+ new TransactionBuilderError ( {
723+ message : `Evaluator returned unknown redeemer tag "${ evalRedeemer . redeemer_tag } " at index ${ evalRedeemer . redeemer_index } . This is likely a provider bug or an unsupported evaluator format.`
724+ } )
684725 )
685726 }
686727 }
0 commit comments