> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-closes-94-guidebook-more.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Hands-on debugging

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

<Aside>
  This guide assumes you use [Blueprint](/contract-dev/blueprint/overview) with [`@ton/sandbox`](/contract-dev/testing/reference). These are common tools for debugging smart contracts.
</Aside>

<Aside>
  All examples from this article are available on [Github](https://github.com/ton-org/docs-examples/tree/main/guidebook/debug)
</Aside>

# Debugging smart contracts

It's a common situation when you encounter an error in your smart contract. In some cases, you will see that an unexpected exit code is returned. This can be a sign of a bug in your contract. There are several techniques to debug your contract.

## Log to the console

A straightforward and effective technique. The most common values to print are transactions and get‑method results.

There are helper functions that let you inspect transactions in a developer‑friendly way.

```ts TypeScript theme={null}
import { toNano } from '@ton/core';
import { Blockchain } from '@ton/sandbox';
import '@ton/test-utils';
import { Test } from './output/sample_Test';
import { findTransaction, flattenTransaction } from '@ton/test-utils';

const setup = async () => {
    const blockchain = await Blockchain.create();
    const owner = await blockchain.treasury('deployer');
    const contract = blockchain.openContract(await Test.fromInit());
    const deployResult = await contract.send(owner.getSender(), { value: toNano(0.5), bounce: true }, null);

    return { blockchain, owner, contract, deployResult };
};

it('should deploy correctly', async () => {
    const { contract, deployResult } = await setup();

    const txToInspect = findTransaction(deployResult.transactions, {
        to: contract.address,
        deploy: true,
    });
    if (txToInspect == undefined) {
        throw new Error('Requested tx was not found.');
    }
    // User-friendly output
    console.log(flattenTransaction(txToInspect));
    // Verbose output
    console.log(txToInspect);
});
```

## Dump values from a contract

Three TVM debug [instructions](/tvm/instructions#fe-debug) exist:

Availability depends on the language you use.

* In Tolk, use functions from the globally available `debug` object.
* In FunC, these methods are available globally in `stdlib.fc`.
* In Tact, use `dumpStack` for `DUMPSTK` and [dump function](https://docs.tact-lang.org/ref/core-debug/#dump) for the other two. Tact also prints the exact line where `dump` is called, so you can quickly find it in your code.

<Aside type="caution">
  Debug instructions consume gas and change measured gas usage. Remove them before deploying and compare gas without debug calls.
</Aside>

## Explore TVM logs

```ts TypeScript theme={null}
const blockchain = await Blockchain.create();
blockchain.verbosity.vmLogs = "vm_logs";
```

There are multiple verbosity levels; two are most useful:

* `vm_logs` — outputs VM logs for each transaction; includes executed instructions and occurred exceptions.
* `vm_logs_full` — outputs full VM logs for each transaction; includes executed instructions with binary offsets, the current stack for each instruction, and gas used by each instruction.

Typical output for `vm_logs` looks like this:

```text theme={null}
...
execute SWAP
execute PUSHCONT x30
execute IFJMP
execute LDU 64
handling exception code 9: cell underflow
default exception handler, terminating vm with exit code 9
```

The contract tries to load a 64‑bit integer (`LDU 64`) from the slice, but there is not enough data, so [exit code 9](/tvm/exit-codes#9%3A-cell-underflow) occurs.

Inspect the same code with the `vm_logs_full` verbosity level. (Output is heavily truncated from the top)

```text theme={null}
...
execute PUSHCONT x30
gas remaining: 999018
stack: [ 500000000 CS{Cell{02b168008d0d4580cd8f09522be7c0390a7a632bda4a99291c435b767c95367ebe78e9af0023d36bc5f97853f4c898f868f95b035ae8f555a321d0ffce8d9f6165e2252d7a9077359400060e9fc800000000003d0902d1b85b3919} bits: 711..711; refs: 2..2} 0 Cont{vmc_std} ]
code cell hash: F9EAC82B7999AEEF696D592FE2469B9069FB05ED35C92213D7EE516F45AB97CA offset: 344
execute IFJMP
gas remaining: 999000
stack: [ 500000000 CS{Cell{02b168008d0d4580cd8f09522be7c0390a7a632bda4a99291c435b767c95367ebe78e9af0023d36bc5f97853f4c898f868f95b035ae8f555a321d0ffce8d9f6165e2252d7a9077359400060e9fc800000000003d0902d1b85b3919} bits: 711..725; refs: 2..2} ]
code cell hash: F9EAC82B7999AEEF696D592FE2469B9069FB05ED35C92213D7EE516F45AB97CA offset: 352
execute LDU 64
handling exception code 9: cell underflow
default exception handler, terminating vm with exit code 9
```

<Aside type="tip">
  If you want to dive deep into the error, you can search the TVM source code for the `LDU` instruction. Note that some instructions in TVM are implemented as instruction groups. For example, [LDU](/tvm/instructions#d3-ldu) (`load_uint`), [LDI](/tvm/instructions#d2-ldi) (`load_int`), it's preload versions `(`preload\_uint`and`preload\_int\`).
</Aside>

Stack is printed as `[bottom, ..., top]`, where `top` is the top of the stack.

Here, the stack contains two values:

* Slice being read
* Integer (`500000000`)

However, the slice has only **725** bits, and **711** bits were already read, as were both references. The contract tried to read **64** bits, but there was not enough data in the slice.

You should locate the `load_uint(64)` call that causes the issue and ensure enough bits are available or adjust the read width.

**TVM log limits**

The size of TVM debug output depends on the verbosity level:

| Level |                                     Setting                                    |        Max size       |
| ----- | :----------------------------------------------------------------------------: | :-------------------: |
| 0     |                                     `none`                                     | 256 bytes *(default)* |
| 1–4   | `vm_logs` <br /> `vm_logs_location` <br /> `vm_logs_gas` <br /> `vm_logs_full` |          1 MB         |
| 5 +   |                           `vm_logs_verbose` and above                          |         32 MB         |

When the output exceeds its limit, it is truncated **from the bottom** —
older entries are discarded, and only the most recent lines are kept.
Logs are **not rotated**.

## Explore the transaction tree

For simple transaction trees, print all transactions and inspect them.

```ts TypeScript theme={null}
const deployRes = await contract.send(owner.getSender(), { value: toNano(0.5), bounce: true }, null);
for (const tx of deployRes.transactions) {
    console.log(flattenTransaction(tx));
}
```

For complex trees, use a GUI tool.

Two tools are commonly used:

* [TonDevWallet trace view](/ecosystem/wallet-apps/dev) — requires the TonDevWallet application; does not require a custom `@ton/sandbox`; requires the `@tondevwallet/traces` package.
* [TxTracer Sandbox](https://txtracer.ton.org/sandbox/) — requires a custom `@ton/sandbox` package; runs in your browser.

Also, these tools allow you to explore each transaction's separate logs.

## Debugging with TVM Retracer

Even when a contract executes successfully (exit code = `0`) with no errors, its actions may not produce the expected on-chain effect. [TVM Retracer](https://retracer.ton.org/) lets you replay the transaction and inspect VM-level execution.

### Scenarios for retracing

* All transaction phases complete without errors, yet the expected outcome is missing.
* An action is skipped, or a transfer does not reach its destination.
* You need a step-by-step view of how the TVM executed your contract logic.

### How to analyze a transaction

1. Obtain the transaction hash from a [blockchain explorer](/ecosystem/explorers/overview).
2. Open [TVM Retracer](https://retracer.ton.org/) and enter the transaction hash.
3. Review the execution:

* Inspect **Logs section** for executed instructions and exceptions.
* Examine **Actions cell (C5)** to review data passed between contracts.
* Check **message modes** — some modes can suppress errors, causing actions to be skipped.
