unionlabs/union · error · Error

waiting for transaction failed

Error message

waiting for transaction failed

What it means

Thrown by waitForTransactionReceipt in the SDK's Aptos transfer flow. The Aptos SDK waitForTransaction is called with checkSuccess: false so it resolves even for failed transactions; the code then inspects transactionResult.success and throws with vm_status as the message (falling back to the literal 'waiting for transaction failed' when the result or vm_status is missing). The outer wrapper prefixes it with 'Waiting for transaction failed:'.

Source

Thrown at typescript-sdk/src/aptos/transfer.ts:53

type AptosTransferParams = Prettify<
  AptosTransferBaseParams & {
    sourceChannel: string
    relayContractAddress: string
  }
>

export const waitForTransactionReceipt: (args: { aptos: Aptos; hash: string }) => ResultAsync<
  string,
  Error
> = ResultAsync.fromThrowable(
  async args => {
    const transactionResult = await args.aptos.waitForTransaction({
      transactionHash: args.hash,
      options: { checkSuccess: false },
    })
    if (!transactionResult?.success) {
      throw new Error(transactionResult.vm_status || "waiting for transaction failed")
    }
    return transactionResult.hash
  },
  error => new Error(`Waiting for transaction failed: ${error}`, { cause: error }),
)

export const buildSimpleTransaction: (args: {
  aptos: Aptos
  accountAddress: AccountAddressInput
  data: InputGenerateTransactionPayloadData
}) => ResultAsync<SimpleTransaction, Error> = ResultAsync.fromThrowable(
  async args =>
    args.aptos.transaction.build.simple({
      data: args.data,
      sender: args.accountAddress,
    }),
  error => new Error(`Build simple transaction failed`, { cause: error }),
)

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Read the vm_status embedded in the wrapped message to identify the Move abort code and act on it
  2. Check the submitting account has APT for gas and the transferred asset exists for the denom address
  3. Verify payload arguments (receiver address, denom, amount) against the relay contract's expected types
  4. Retry after confirming the transaction hash on an Aptos explorer in case of node/indexer lag
Defensive patterns

Strategy: retry

Try / catch

try {
  hash = await waitForTransactionReceipt({ aptos, hash }).toPromise()
} catch (error) {
  const msg = (error as Error).message
  if (msg.startsWith("Waiting for transaction failed:")) {
    const vmStatus = msg.replace("Waiting for transaction failed:", "").trim()
    if (/out of gas|too many resources/i.test(vmStatus)) {
      // rebuild tx with higher max gas and resubmit
    } else {
      // surface vmStatus (Move abort code) to the user; do not blind-retry aborted txs
    }
  } else {
    throw error
  }
}

Prevention

When it happens

Trigger: A submitted Aptos transaction that was included but aborted in the Move VM (execution error, MOVE abort code, out of gas, insufficient balance, failed ibc::send payload arguments), or waitForTransaction returning an unexpectedly empty/undefined result.

Common situations: IBC transfer from Aptos where the send payload arguments are wrong (denom, timeout heights); account has no APT for gas on mainnet/testnet; gas parameters (e.g. 999_999_999 max gas) rejected by the network; node lag causing a null result.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/2d9d912a98c74d23. Report an issue: GitHub.