Sui.

Post

Share your knowledge.

Bounty+15

Bolke .
Aug 12, 2025
Expert Q&A

Sui Move Error - Unable to process transaction No valid gas coins found for the transaction

When I do this:

        // Split payment from primary coin
        const [paymentCoin] = tx.splitCoins(
            tx.object(primaryCoin.coinObjectId),
            [tx.pure.u64(requiredPaymentAmount)]
        );

        // Use the original coin for gas payment
        tx.setGasPayment([{
            objectId: primaryCoin.coinObjectId,
            version: primaryCoin.version,
            digest: primaryCoin.digest
        }]);

        tx.setGasBudget(10_000_000);

It complains about mutatable objects cannot appear more than one in one transaction. When I remove the gas payment, it complains "Unable to process transaction No valid gas coins found for the transaction.". My contract function accepts .01 sui in exchange for an NFT

  • Sui
  • Transaction Processing
  • Move
4
19
Share
Comments
.

Answers

19
MoonBags.
Sep 4 2025, 03:43

You are running into a core Sui Move and Sui transaction model restriction: the same coin object cannot be used both as a gas coin and as an input to another command in the same transaction. This is enforced to prevent double-spending and ensure transaction safety.

Why this happens

  • When you use primaryCoin in splitCoins, it becomes a mutable input to the transaction.
  • When you also set it as the gas coin (setGasPayment), you are trying to use the same object in two roles.
  • Sui does not allow a mutable object (like a coin being split) to also be used as the gas coin in the same transaction.

This is confirmed by the error in your context:

mutatable objects cannot appear more than one in one transaction

And in the Sui Move test context:

Invalid taking of the Gas coin. It can only be used by-value with TransferObjects
(see source)

What you need to do

You must use a different coin for gas than the one you are splitting or otherwise mutating in the transaction.

Solution

  1. Ensure you have at least two SUI coins in your wallet.
  2. Use one coin for splitting/payment, and another for gas.

Example Flow

Suppose you have two coins: primaryCoin and gasCoin.

// Split payment from primary coin (not used for gas)
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);

// Set a different coin for gas payment
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);

tx.setGasBudget(10_000_000);
  • primaryCoin is used for splitting and payment.
  • gasCoin is used only for gas.

If you only have one coin, you must first split it in a separate transaction, so you have two coins for the next transaction.


References

8
Comments
.
0xduckmove.
Sep 4 2025, 04:52

This is a fundamental design choice in Sui to ensure transaction safety and prevent double-spending. It can be confusing at first, but once you get used to always keeping at least two coins in your wallet (one for gas, one for other operations), it becomes second nature. If you ever run into this error, just remember: never use the same coin for both gas and as a mutable input in the same transaction

Carnelian.
Sep 4 2025, 05:01

Always select a distinct coin object for gas payment, separate from any coin you intend to mutate or transfer. If you only have one coin, split it in a prior transaction to create a second coin object for subsequent operations.

0xduckmove.
Aug 13 2025, 03:14

You are running into a common Sui Move transaction design constraint the same coin object cannot be used both as a mutable input (e.g., for splitting or transferring) and as the gas coin in a single transaction.

Why this happens

  • When you use tx.splitCoins(tx.object(primaryCoin.coinObjectId), ...), you are marking primaryCoin as a mutable input.
  • When you also set it as the gas coin with tx.setGasPayment(...), Sui sees the same object being used in two roles, which is not allowed.
  • If you remove the gas payment, Sui cannot find a valid gas coin, hence the "No valid gas coins found for the transaction" error.

From context:

Transaction Effects Status: Invalid usage of value. Mutably borrowed values require unique usage. Immutably borrowed values cannot be taken or borrowed mutably. Taken values cannot be used again. (source)

How to fix

You must use a different coin for gas than the one you are splitting or transferring.

The Solution: Have at least two SUI coins in your wallet. Use one for the payment (splitting/transferring), and a different one for gas.

Example Flow

  1. Select two coins:
  • primaryCoin (for payment)
  • gasCoin (for gas)
  1. Split and pay with primaryCoin:
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);
  1. Set gas payment with gasCoin:
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);
tx.setGasBudget(10_000_000);

Do not use the same coin object for both payment and gas.

My Reference

Sui Move: Invalid taking of the Gas coin. It can only be used by-value with TransferObjects

5
Comments
.
Owen.
Owen4662
Aug 13 2025, 06:10

The error occurs because you're trying to use the original primaryCoin object (which is consumed during the splitCoins operation) as gas payment. After splitting, the original coin's version/digest becomes invalid, causing the "mutatable objects cannot appear more than one" error when referenced again.

To fix do not manually set gas payment using the pre-split primaryCoin object. And nsure your primaryCoin has sufficient balance to cover both:

  • The payment amount (requiredPaymentAmount = 0.01 SUI)
  • The gas budget (10_000_000 = 0.01 SUI) → Total needed: ≥ 0.02 SUI

Just try

// Split payment from primary coin (leaves remaining balance in primaryCoin)
const [paymentCoin] = tx.splitCoins(
  tx.object(primaryCoin.coinObjectId),
  [tx.pure.u64(requiredPaymentAmount)]
);

// DO NOT setGasPayment manually - SDK auto-uses updated primaryCoin for gas
tx.setGasBudget(10_000_000); // Gas paid from primaryCoin's remaining balance
4
Comments
.
Gifted.eth.
Aug 22 2025, 00:57

Bravo!!!

Redterror.
Aug 15 2025, 10:50

To fix the problem you're running into with the Sui transaction error about no valid gas coins found or mutable objects showing up more than once, it's because you can't use the same coin for both splitting off the payment and covering gas fees, as gas coins need to stay separate from the items you're tweaking in the deal. The easy tweak is to split the payment straight from the gas source instead of your main coin, so change it to something like

const paymentCoin = tx.splitCoins(tx.gas(), [tx.pure.u64(requiredPaymentAmount)]);

then drop the manual gas payment line altogether since the system will pick it up on its own, and keep your gas budget set as usual. This lets you pull from the gas coin without clashing, as long as your wallet has plenty to handle the 0.01 Sui payment plus fees.

4
Comments
.
MiniBob.
Aug 12 2025, 19:33

This happens because you're trying to use the same coin object (primaryCoin) both as gas payment and as input to splitCoins, which makes it a mutable reference used in two different contexts — and Sui doesn't allow that for safety and linear logic (since coins are linear objects).

The way IMHO is to not manually set gas payment at all. Just let the Sui wallet/client automatically select an appropriate gas coin. Only use setGasPayment if you really need to specify which coin pays for gas (e.g., multi-coin wallets, specific gas management). Otherwise, avoid it.

Try the following:

// Split the primary coin to get a payment coin
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);

// Do your call that sends .01 SUI and gets an NFT
tx.moveCall({
    target: `${packageId}::your_module::buy_nft`,
    arguments: [
        paymentCoin,
        // other args...
    ],
});

// DO NOT set gas payment manually
// tx.setGasPayment(...) ← Remove this line

// Optional: set budget
tx.setGasBudget(10_000_000);

// Send the transaction
const result = await signer.signAndExecuteTransactionBlock({
    transactionBlock: tx,
    options: { showEffects: true },
});

Sui will:

  • Automatically choose a gas coin (could be the same one or another SUI coin in the wallet).
  • Handle the splitCoins safely.
  • Use a different coin (or sometimes the same one, but handled safely under the hood via proper object versioning).

Important: As long as your wallet has at least 1 $SUI that can cover gas, this will work.

3
Comments
.
BigDev.
Aug 15 2025, 16:20

This issue happens because you’re using the same coin (primaryCoin) for both gas and as an input in splitCoins, which isn’t allowed in Sui due to its rules around linear objects and safe mutation.

To fix it, don’t manually set the gas payment. Let the Sui wallet or client auto-select a suitable gas coin. You only need setGasPayment in advanced cases (like precise coin control). Here’s the clean approach:


// Split the primary coin to create a new payment coin
const [paymentCoin] = tx.splitCoins(
  tx.object(primaryCoin.coinObjectId),
  [tx.pure.u64(requiredPaymentAmount)]
);

// Call your function using the new coin
tx.moveCall({
  target: ${packageId}::your_module::buy_nft,
  arguments: [paymentCoin],
});

// No manual gas setting — remove tx.setGasPayment(...)

// Set your gas budget
tx.setGasBudget(10_000_000);

// Execute the transaction
const result = await signer.signAndExecuteTransactionBlock({
  transactionBlock: tx,
  options: { showEffects: true },
});

Sui will safely pick a gas coin from your wallet (as long as one is available) and handle everything behind the scenes

3
Comments
.
Carnelian.
Aug 30 2025, 15:10

This error happens because you’re trying to use the same coin both as the gas object and for a split operation, which breaks Sui’s rule against having two mutable references to the same object in one transaction. Splitting primaryCoin modifies it while also producing a new coin, and both can’t coexist in the same transaction. To fix this, you should:

* Use separate coins: one dedicated for gas, another for splitting or payments.
* Or, merge enough balance from another coin into primaryCoin before the transaction so it can cover all costs without duplication.

In short: always ensure that the coin used for gas is different from the one being split or passed into contract calls to prevent conflicts.

3
Comments
.
Paul.
Paul4340
Aug 13 2025, 08:48

Issues

You're encountering two main issues:

  1. Mutability Error: Attempting to use the same coin object for both gas payment and transaction input leads to the error: "Mutable objects cannot appear more than once in one transaction."

  2. Missing Gas Coin: Without a valid gas coin, the error "Unable to process transaction: No valid gas coins found for the transaction" occurs.


Solution

To resolve these issues:

  1. Split the Primary Coin for Payment: Use tx.splitCoins to create a new coin for the NFT purchase, ensuring it's separate from the gas payment.

  2. Set a Separate Gas Coin: Assign a different coin for gas payment using tx.setGasPayment.

  3. Define Gas Budget: Set an appropriate gas budget using tx.setGasBudget.


Code

// Step 1: Split the primary coin for payment
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);

// Step 2: Set a separate gas payment coin
const gasCoin = tx.object(gasCoinObjectId);
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);

// Step 3: Set the gas budget for the transaction
tx.setGasBudget(10_000_000);
2
Comments
.
Benjamin XDV.
Aug 22 2025, 11:08

The error occurs because you're attempting to split and use the same coin for both payment and gas, violating Sui's rule against mutable object duplication in a transaction. When you split primaryCoin, it creates a new coin while mutating the original—both cannot appear in the same transaction. To resolve this, use two separate coins: one for gas payment and another for the split payment operation. Alternatively, merge sufficient gas from another coin into primaryCoin before the transaction to cover both costs, ensuring only one mutable reference exists. Always verify gas coins are distinct from those being split or used in contract calls to avoid conflicts.

2
Comments
.
Gifted.eth.
Aug 22 2025, 15:01

I hope you got solution for this huh?

Evgeniy CRYPTOCOIN.
Aug 22 2025, 11:19

You can’t use the same coin for both payment and gas. Fix:

  1. Split Gas First – Create a separate gas coin:
    const [gasCoin] = tx.splitCoins(tx.object(primaryCoinId), [tx.pure(10_000_000)]);  
    tx.setGasPayment([gasCoin]);  
    
  2. Then Split Payment – Use the remaining balance for your NFT payment.

Key Rule:
✔ Each coin can only be used once per transaction.

Alternative: Use two separate coins (if available).

(Sui requires distinct coins for gas and payments to avoid conflicts.)

1
Comments
.
Arnold.
Arnold3036
Aug 22 2025, 12:00

The error happens because you're trying to use the same coin object for two different things: splitting to make a payment and paying for gas. The system sees this as trying to use one object mutably twice in a single transaction, which isn't allowed.

You need a separate coin to pay for gas. Here's the fix:

  1. Use a different gas coin: Find another coin in your wallet's list of SUI coins to specify as the gasPayment. Don't use the primaryCoin you're splitting.

  2. Or, merge coins first: If you only have one coin, you might need to merge some smaller coins into it first to create a separate gas coin. Then use one for the split/payment and the other for gas.

The key is that the coin you use for setGasPayment must be completely separate from any coins you're splitting or using in the transaction's commands.

1
Comments
.
Gifted.eth.
Aug 22 2025, 14:57

Bravo!!!

chaincrafter.
Sep 13 2025, 22:05

That error on Sui:

“Unable to process transaction – No valid gas coins found for the transaction”

means your wallet doesn’t currently have any SUI tokens that can be used as gas fees. Every transaction on Sui — whether sending tokens, minting NFTs, or interacting with dApps — requires a small amount of SUI to pay for gas.


🔍 Why It Happens

  • No SUI balance: You don’t have any SUI in your wallet.
  • Coin is too small: Sometimes SUI is “locked” in very tiny amounts (dust coins) that are not enough to cover gas.
  • Wrong network: You may be on Testnet or Devnet but don’t have test SUI loaded.
  • Wallet not refreshed: Rarely, the wallet UI lags behind and doesn’t recognize available coins.

✅ How to Fix It

If You’re on Mainnet

  1. Get some SUI tokens

    • Buy SUI from an exchange (Binance, KuCoin, OKX, etc.) and withdraw to your wallet.
    • Or receive SUI from a friend/wallet that already has some.
  2. Check for Coin Splitting

    • Sometimes you have SUI, but it’s fragmented into unusable “dust.”
    • Use the “Merge Coins” feature in Sui Wallet (found under your SU
  3. Use a Faucet

    • Go to the official Sui faucet: https://faucet.sui.io

    • Or, on Discord (in the Sui Discord server), go to the #testnet-faucet channel and type:

      !faucet <your_sui_address>
      
    • This will send you free testnet SUI.

  4. Switch Networks Properly

    • In your Sui Wallet extension → click profile icon → select Testnet or Devnet depending on where you’re working.

⚠️ Tip

Always keep a small reserve of SUI in your wallet for gas (like 0.05–0.1 SUI). If you send your entire balance out, you won’t have gas left to make the next transaction.


Do you want me to walk you through getting testnet SUI from the faucet right now, or are you running into this issue on mainnet with real tokens?

0
Comments
.

Do you know the answer?

Please log in and share it.