Description
When a Stellar transaction fails, Horizon returns structured error codes in the result_codes field — codes like tx_bad_seq, op_no_trust, op_underfunded, op_no_destination. Currently the backend marks the transaction as successful: false and returns a generic summary. Users have no idea why their transaction failed.
This issue parses Horizon result codes and adds a human-readable failure_reason field to the transaction explanation that tells the user exactly what went wrong and how to fix it.
Horizon Error Response
When a transaction fails, Horizon includes:
{
"extras": {
"result_codes": {
"transaction": "tx_bad_seq",
"operations": ["op_no_trust", "op_success"]
}
}
}
Target Response Addition
{
"successful": false,
"failure_reason": "Transaction failed: sequence number is out of date. This usually means another transaction was submitted from this account simultaneously. Try again.",
"operation_failures": [
{
"index": 0,
"code": "op_no_trust",
"explanation": "This account has not opted in to hold this asset. The sender needs to establish a trust line before receiving it."
}
]
}
Error Codes to Translate
Transaction-level codes (result_codes.transaction)
| Code |
Plain-English explanation |
tx_bad_seq |
Sequence number is out of date — another transaction from this account may have been submitted first. Try again. |
tx_bad_auth |
The transaction was not properly signed by the required keys. |
tx_insufficient_balance |
The account does not have enough XLM to cover this transaction and the minimum balance. |
tx_no_account |
The source account does not exist on the Stellar network. |
tx_insufficient_fee |
The fee offered was too low. |
tx_too_early |
The transaction was submitted before its min_time boundary. |
tx_too_late |
The transaction expired before it was processed. |
tx_missing_operation |
The transaction contains no operations. |
tx_bad_auth_extra |
The transaction has more signatures than required. |
Operation-level codes (result_codes.operations[])
| Code |
Plain-English explanation |
op_no_trust |
The destination account has not opted in to hold this asset. |
op_underfunded |
The source account does not have enough of this asset to send. |
op_no_destination |
The destination account does not exist on the Stellar network. |
op_not_authorized |
The asset issuer has not authorised this account to hold the asset. |
op_line_full |
The destination account's trust line is full and cannot receive more. |
op_no_issuer |
The asset issuer account does not exist. |
op_low_reserve |
The account would fall below the minimum XLM reserve after this operation. |
Key Files
packages/core/src/explain/failure.rs — new file, maps error codes to explanations
packages/core/src/models/transaction.rs — add failure_reason and operation_failures fields
packages/core/src/services/horizon.rs — parse extras.result_codes from Horizon error response
packages/core/src/explain/transaction.rs — wire failure explanations into the response
Acceptance Criteria
Complexity: High · 200 pts
Description
When a Stellar transaction fails, Horizon returns structured error codes in the
result_codesfield — codes liketx_bad_seq,op_no_trust,op_underfunded,op_no_destination. Currently the backend marks the transaction assuccessful: falseand returns a generic summary. Users have no idea why their transaction failed.This issue parses Horizon result codes and adds a human-readable
failure_reasonfield to the transaction explanation that tells the user exactly what went wrong and how to fix it.Horizon Error Response
When a transaction fails, Horizon includes:
{ "extras": { "result_codes": { "transaction": "tx_bad_seq", "operations": ["op_no_trust", "op_success"] } } }Target Response Addition
{ "successful": false, "failure_reason": "Transaction failed: sequence number is out of date. This usually means another transaction was submitted from this account simultaneously. Try again.", "operation_failures": [ { "index": 0, "code": "op_no_trust", "explanation": "This account has not opted in to hold this asset. The sender needs to establish a trust line before receiving it." } ] }Error Codes to Translate
Transaction-level codes (
result_codes.transaction)tx_bad_seqtx_bad_authtx_insufficient_balancetx_no_accounttx_insufficient_feetx_too_earlymin_timeboundary.tx_too_latetx_missing_operationtx_bad_auth_extraOperation-level codes (
result_codes.operations[])op_no_trustop_underfundedop_no_destinationop_not_authorizedop_line_fullop_no_issuerop_low_reserveKey Files
packages/core/src/explain/failure.rs— new file, maps error codes to explanationspackages/core/src/models/transaction.rs— addfailure_reasonandoperation_failuresfieldspackages/core/src/services/horizon.rs— parseextras.result_codesfrom Horizon error responsepackages/core/src/explain/transaction.rs— wire failure explanations into the responseAcceptance Criteria
failure_reasonwith a plain-English explanationoperation_failures[]array present when operations also have error codesfailure_reason: nullandoperation_failures: []cargo testpasses with no regressionsComplexity: High · 200 pts