Back-to-back transactions produce ValueNotConservedUTxO error

I recently wrote some scripts that mint and send tokens. When I run the script to mint a token and then immediately run the script to send that token to a wallet, I get this error:Preformatted text

Error: Command failed: cardano-cli transaction submit --testnet-magic 1097911063 --tx-file ./tmp/tx_n5sm4btig.signed
Command failed: transaction submit  Error: Error while submitting tx: ShelleyTxValidationErrorShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (ValueNotConservedUTxO (Value 0 (fromList [(PolicyID {policyID = ScriptHash "1a1b09e939ec7fd1b60c1e4d71808926421079f679e79d1e9f36561a"},fromList [("TestNFT",1)])])) (Value 992262587 (fromList [(PolicyID {policyID = ScriptHash "1a1b09e939ec7fd1b60c1e4d71808926421079f679e79d1e9f36561a"},fromList [("TestNFT",1)]),(PolicyID {policyID = ScriptHash "584af528f36789c8d5cc9336ec258326cbea8b3983d9d6d40cdc5bce"},fromList [("TestNFT",1)]),(PolicyID {policyID = ScriptHash "6eee44f15e11b84d33bcaaff8096d36fa400f6cb8eaa14007d6fac1b"},fromList [("TestNFT",1)]),(PolicyID {policyID = ScriptHash "b294451d861bc02b49591d9413a12f8b24a0f17c57940c9d78d1074c"},fromList [("TestNFT",1)]),(PolicyID {policyID = ScriptHash "e7ba14bfcb30f171b106ea15984cd25101d73f72fc89f2bb864ff600"},fromList [("TestNFT",1)])]))))),UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (BadInputsUTxO (fromList [TxIn (TxId {_unTxId = SafeHash "7d667aef6319a22a71903fca4d88b69cea24e23c36120e11f34738aa8d90da07"}) 0]))))])

A similar error happens if I run the script to mint a token and then immediately re-run it. It seems like rapid back-to-back transactions cause this. Am I doing something incorrectly?

Edit: I wanted to add that the scripts work as expected if there is a pause (>~1 minute) between each execution.

Any help is appreciated, and I apologize if this is a basic question!

The first Tx probably consumes some UTxO from the sender (i.e. to pay fees for minting). When you submit the Tx to the network and then immediately query the sender address for UTxO (i.e. to pay fees for the next Tx) it is likely that the first UTxO has not yet consumed and still shows up in the query. When you send the second Tx with the same (fee) UTxO as the first, you would attempt a classic double spend, which the network correctly rejects (i.e. an UTxO can only be spent ones).

If you wait a little, the first UTxO will be spent and a new one (i.e. the refund from the first Tx) will show up in your query.

You could try to maintaining a blacklist of UTxO that your script already used. The script would then not use the same UTxO again and instead use another or wait until another becomes available.

That makes sense. Thank you! I solved the immediate problem by minting and sending in the same transaction. For double spending, I’ll try the approach of queueing up the transactions I want to send and then sending them as UTxOs become available.