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
- Read the vm_status embedded in the wrapped message to identify the Move abort code and act on it
- Check the submitting account has APT for gas and the transferred asset exists for the denom address
- Verify payload arguments (receiver address, denom, amount) against the relay contract's expected types
- 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
- Pre-fund accounts with gas APT before transfers
- Validate receiver/denom/amount arguments before submitting to avoid Move aborts
- Treat vm_status as the source of truth; only retry on transient node errors, not deterministic aborts
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
- simulation result not found
- Transaction failed: ${transaction?.vm_status} - ${JSON.strin
- hash not found
- No Aptos RPC URL found
- no `signer` passed
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/2d9d912a98c74d23.
Report an issue: GitHub.