unionlabs/union · error · Error
Transaction failed: ${transaction?.vm_status} - ${JSON.strin
Error message
Transaction failed: ${transaction?.vm_status} - ${JSON.stringify(transaction, undefined, 2)} What it means
Thrown in transferAssetFromAptos on the wallet path after signAndSubmitTransaction: the returned transaction object either failed on-chain or lacks a truthy success field, and the error embeds vm_status plus a pretty-printed JSON dump of the whole transaction so nothing is lost. Note that a pending submission response often has no success field, in which case the JSON dump is the only diagnostic.
Source
Thrown at typescript-sdk/src/aptos/transfer.ts:146
function: payload.function,
type_arguments: payload.typeArguments,
arguments: [
parameters.sourceChannel,
isValidBech32Address(parameters.receiver)
? bech32AddressToHex({ address: parameters.receiver })
: parameters.receiver,
[parameters.denomAddress],
[parameters.amount.toString()],
parameters.memo ?? "",
BigInt(9n).toString(),
BigInt(999_999_999).toString(),
BigInt(0n).toString(),
],
},
})
if (!transaction?.success) {
throw new Error(
`Transaction failed: ${transaction?.vm_status} - ${
JSON.stringify(transaction, undefined, 2)
}`,
)
}
return transaction.hash
}
const signer = parameters.signer as AptosAccount
const transaction = await buildSimpleTransaction({
data: payload,
aptos: parameters.aptos,
accountAddress: signer.accountAddress,
})
if (!transaction.isOk()) {
throw transaction.errorView on GitHub (pinned to 031785bb6d)
Solutions
- Read the vm_status and JSON dump in the message to determine whether it is a real on-chain failure or a response-shape issue
- If it is a response-shape issue (no success field on a pending tx), poll waitForTransaction with the returned hash instead of relying on the submit response
- Verify the ibc::send arguments (denom address, receiver, amount string, timeout heights) and account gas balance
- Update the wallet adapter / SDK versions so signAndSubmitTransaction returns the documented shape
Defensive patterns
Strategy: try-catch
Try / catch
try {
hash = await transferAssetFromAptos(params).toPromise()
} catch (error) {
const msg = (error as Error).message
if (msg.startsWith("Transfer failed: Transaction failed:")) {
const dumped = msg.slice(msg.indexOf("{")) // JSON dump starts at the opening brace
// parse the dump: real VM abort vs response without success field
}
throw error
} Prevention
- After any wallet submit, confirm final state with waitForTransaction(hash) rather than trusting the submit response alone
- Log the full JSON dump when triaging — it contains gas usage, status, and events
- Keep wallet adapter versions current so response shapes match SDK expectations
When it happens
Trigger: A wallet-signed cross-chain (ibc::send) Aptos transaction whose result is not marked successful: Move abort inside the relay entrypoint, gas exhaustion, malformed arguments, or a wallet SDK response shape without success that the strict check treats as failure.
Common situations: Browser wallet (Petra/Pontem) submissions of IBC transfers; user's account out of gas; memo/timeout arguments built incorrectly; wallet adapter returning a pending-transaction object rather than the full transaction view.
Related errors
- waiting for transaction failed
- simulation result not found
- 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/55567aa2abd6c80b.
Report an issue: GitHub.