How to Handle Transaction Failures and Error Responses from the Osmosis Blockchain

To handle transaction failures in the Osmosis Agent Toolkit, wrap signAndBroadcast calls in try/catch blocks, inspect the BroadcastTxResponse for non-zero code values, and check rawLog for on-chain error details.

The Osmosis Agent Toolkit provides a high-level Account class in packages/core/src/account.ts that abstracts Cosmos SDK transaction signing and broadcasting. When you submit transactions to the Osmosis blockchain, the toolkit exposes raw error responses that require explicit handling to distinguish between network failures, simulation errors, and on-chain rejections.

Understanding the Transaction Flow in Osmosis Agent Toolkit

The Account.signAndBroadcast Method

In packages/core/src/account.ts (lines 107-115), the Account class implements the signAndBroadcast method, which internally instantiates a SigningStargateClient and calls signAndBroadcastSync. This method returns a BroadcastTxResponse object containing the transaction hash, block height, and critical error metadata.

// Simplified flow from account.ts
const client = await SigningStargateClient.connectWithSigner(
  this.rpcEndpoint,
  this.wallet,
  this.clientOptions
);
const response = await client.signAndBroadcastSync(signerAddress, messages, fee, memo);

The BroadcastTxResponse Structure

When CosmJS processes your transaction, it returns a BroadcastTxResponse with these key fields:

  • code: 0 indicates success; non-zero values indicate specific failure types (e.g., code 5 typically means insufficient funds).
  • rawLog: A human-readable string containing the detailed error message from the Osmosis chain.
  • txhash: The transaction hash (present even for failed transactions that made it on-chain).

Tool Layer Integration

Higher-level tools like SendSwapInGivenOutQuoteTxTool call account.signAndBroadcast internally. In packages/core/src/tools/swap.ts (lines 244-252), these tools typically extract only the txHash from the response, swallowing the full error details unless you modify the implementation.

Common Blockchain Transaction Failure Modes

Simulation and Fee Estimation Errors

Before broadcasting, the toolkit calls estimateFee (implemented near line 258-268 in account.ts) to simulate the transaction. If the simulation fails—due to invalid parameters or insufficient gas settings—CosmJS throws an exception before any BroadcastTxResponse is generated.

Network and RPC Broadcast Failures

Connectivity issues trigger runtime errors with messages like "No RPC endpoint found" (see account.ts line 202). These manifest as thrown JavaScript Error objects rather than structured response codes.

On-Chain Transaction Rejections

When a transaction reaches the Osmosis blockchain but fails execution (e.g., slippage tolerance exceeded, invalid pool ID, or out-of-gas), the node includes the transaction in a block with a non-zero code. The rawLog field contains the specific error message from the Cosmos SDK module.

Best Practices for Error Handling

Wrapping Tool Calls in Try-Catch Blocks

Always wrap tool invocations in try/catch to capture both network errors and unexpected runtime failures:

import { SendSwapInGivenOutQuoteTxTool } from '@osmosis-agent-toolkit/core';

async function executeSwap(tool: SendSwapInGivenOutQuoteTxTool, params: object) {
  try {
    const { txHash } = await tool.call(params);
    console.log(`✅ Tx submitted: ${txHash}`);
    return txHash;
  } catch (err) {
    if (err instanceof Error) {
      console.error('⚠️ Broadcast failed:', err.message);
      // Handle RPC errors or simulation failures
      throw err;
    }
  }
}

Inspecting BroadcastTxResponse for Failure Codes

For granular error diagnostics, bypass the high-level tool abstraction and interact directly with the Account class to access the full BroadcastTxResponse:

import type { BroadcastTxResponse } from '@cosmjs/stargate';
import { Account } from '@osmosis-agent-toolkit/core';

async function broadcastWithErrorHandling(
  account: Account,
  messages: EncodeObject[]
): Promise<BroadcastTxResponse> {
  const resp = await account.signAndBroadcast({ msgs: messages });
  
  if (resp.code !== 0) {
    console.error('❌ Transaction failed');
    console.error('Error Code:', resp.code);
    console.error('Details:', resp.rawLog);
    // Implement retry logic or user notification here
  } else {
    console.log('✅ Success:', resp.txhash);
  }
  return resp;
}

Distinguishing Network Errors from On-Chain Failures

Structure your error handling to differentiate between pre-broadcast exceptions and post-broadcast failures:

  1. Network/SDK errors: Thrown as JavaScript Error objects during signAndBroadcast (RPC unreachable, simulation failed).
  2. On-chain failures: Returned as valid BroadcastTxResponse objects with code !== 0 (insufficient funds, invalid state).

Practical Implementation: Handling Swap Transaction Failures

This complete example demonstrates robust error handling for swap operations using the SendSwapOutGivenInQuoteTxTool:

import { Account, SendSwapOutGivenInQuoteTxTool, ToolMemory } from '@osmosis-agent-toolkit/core';
import type { SidecarOutGivenInQuoteResponse } from '@osmosis-agent-toolkit/core';

const mnemonic = process.env.OSMOSIS_MNEMONIC!;
const account = new Account(mnemonic);
const memory = new ToolMemory<string, SidecarOutGivenInQuoteResponse>();
const swapTool = new SendSwapOutGivenInQuoteTxTool(account, memory);

const params = {
  quoteId: 'abc123',
  slippageTolerancePercent: 0.5,
};

async function runSwap() {
  try {
    const result = await swapTool.call(params);
    console.log('✅ Swap submitted, txHash:', result.txHash);
  } catch (error) {
    if (error instanceof Error) {
      console.error('🚨 Network or simulation error:', error.message);
      // Likely RPC failure or fee estimation failure (account.ts L258-268)
    } else {
      console.error('🚨 Unknown error:', error);
    }
  }
}

runSwap();

To access the full BroadcastTxResponse including error codes, extend the tool or call account.signAndBroadcast directly as shown in the previous section.

Summary

  • Wrap every transaction broadcast in try/catch blocks to catch CosmJS network errors and simulation failures.
  • Inspect BroadcastTxResponse.code where 0 equals success and non-zero indicates specific on-chain failures.
  • Read BroadcastTxResponse.rawLog to extract human-readable error messages from the Osmosis blockchain.
  • Handle estimateFee errors separately; these throw exceptions before the transaction reaches the network.
  • For complete error diagnostics, call Account.signAndBroadcast directly rather than relying on tools that return only the transaction hash.

Frequently Asked Questions

What error code indicates insufficient funds in Osmosis?

Error code 5 typically indicates insufficient funds or insufficient fees in Cosmos SDK chains including Osmosis. When you receive a BroadcastTxResponse with code: 5, check the rawLog field for details about the specific denomination and amount required.

How do I access the full error message when a transaction fails on-chain?

Instead of using high-level tools that return only { txHash }, call account.signAndBroadcast({ msgs }) directly from packages/core/src/account.ts. The returned BroadcastTxResponse object contains the rawLog property with the complete error message from the blockchain.

Should I catch errors at the tool level or the Account level?

Catch errors at the outermost application layer that invokes the toolkit. The tools in packages/core/src/tools/swap.ts propagate both thrown exceptions (network errors) and successful responses, so wrapping the tool.call() or account.signAndBroadcast() invocation in a single try/catch block handles all failure modes.

What is the difference between signAndBroadcast and signAndBroadcastSync?

According to the CosmJS implementation used in account.ts (line 115), signAndBroadcastSync submits the transaction and returns immediately once it is included in the mempool, providing a BroadcastTxResponse. The signAndBroadcast method in the Osmosis Agent Toolkit wraps this call and returns the same response type, allowing you to handle both synchronous validation errors and asynchronous on-chain failures through the code and rawLog fields.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →