This page covers common questions, confusing behaviors, and troubleshooting tips for the Soroban Debugger (soroban-debug).
- Installation
- Running Contracts
- Breakpoints
- Budget
- Output and Trace
- Argument Parsing
- CLI vs VS Code Extension
- Local and CI Environment
Cause: Your system lacks the necessary build tools (C compiler and linker) required to compile Rust dependencies. Fix:
- Windows: Install Visual Studio Build Tools and select the "Desktop development with C++" workload.
- Linux: Install
build-essential(Ubuntu/Debian) orbase-devel(Arch). - macOS: Run
xcode-select --install.
Cause: cargo install only installs the binary, not the manual pages.
Fix: If building from source, manually copy the man pages:
sudo cp man/man1/soroban-debug* /usr/local/share/man/man1/Then use man soroban-debug.
Cause: The project uses modern Rust features. Fix: Update your Rust toolchain:
rustup updateCause: The path provided to --contract is incorrect or relative to a different directory.
Fix: Ensure the path is correct relative to your current working directory. Use an absolute path if unsure.
soroban-debug run --contract ./target/wasm32-unknown-unknown/release/my_contract.wasm ...Cause: The function name specified with --function is not exported by the WASM contract or is misspelled.
Fix: Use the inspect command to see all available exported functions:
soroban-debug inspect --contract my_contract.wasmCause: This occurs when a contract triggers a host panic that isn't mapped to a specific error code, or when a Rust panic! occurs without a descriptive message.
Fix:
- Use the
logscommand ininteractivemode to see the host-level diagnostic events leading up to the panic. - Check for common Rust panics:
unwrap()onNone, out-of-bounds array access, or integer overflow. - Ensure all contract dependencies are compatible with the current Soroban host version.
Cause: You might be setting a breakpoint on a function that is never called, or the function name is slightly different (e.g., due to name mangling).
Fix: Verify the function name using soroban-debug inspect. In interactive mode, use list-breaks to ensure your breakpoints are registered.
Answer: Currently, the debugger supports setting breakpoints only at function boundaries.
Workaround: Set a breakpoint at the function containing the line, then use s (step) or n (next) to reach the specific line.
Cause: Source verification and runtime binding are different decisions in the adapter. Meaning:
verified=falsemeans an exact source map proof was not available.setBreakpoint=truemeans the adapter still bound a runtime function breakpoint.HEURISTIC_NO_DWARFmeans DWARF source mapping was unavailable and the adapter used heuristic function mapping.
Example: A breakpoint on lib.rs:10 may return verified=false with HEURISTIC_NO_DWARF, yet still pause at runtime if that line is inside an exported entrypoint function.
Cause: The contract has consumed a significant portion of the Soroban CPU budget.
Fix: Optimize expensive loops, reduce deep recursion, or minimize complex storage operations. Use the budget command in interactive mode to see which parts of your code are the most "expensive".
Cause: The execution hit the maximum allowed Soroban resource limits. Fix: Check for infinite loops or extremely inefficient algorithms. You can also try to provide a larger initial budget if your local environment allows (though on-chain limits will still apply).
Cause: The debugger environment might have slight overhead or use a different version of the Soroban host than the network you are targeting. Fix: Use budget numbers as a relative guide for optimization rather than an absolute guarantee for on-chain costs.
Cause: Shell quoting issues are common. If your JSON contains double quotes, the shell might be stripping them. Fix: Wrap the entire JSON string in single quotes:
soroban-debug run --args '["Alice", "Bob", 100]'Cause: The value provided exceeds the range of the target type (e.g., u32 max is ~4.29 billion).
Fix: Ensure your input fits within the specified type, or use a larger type like u64 or i128 (default).
Answer: Use the explicit type annotation for addresses. Fix:
{"type": "address", "value": "CCV6S6F6..."}Or, if it's a 56-character string starting with 'C' or 'G', the debugger will often auto-detect it as an Address.
Cause: Exporting every storage change and event can lead to huge JSON files.
Fix: Use --storage-filter to only include the keys you care about in the output, which will also reduce the trace size.
soroban-debug run --trace-output trace.json --storage-filter 'balance:*'Cause: Your terminal might not support Unicode box-drawing characters or ANSI colors.
Fix: Use the --no-unicode flag and set the NO_COLOR=1 environment variable:
NO_COLOR=1 soroban-debug run --no-unicode ...Answer: The CLI and the VS Code extension do not have full feature parity. The CLI exposes the complete debugger surface; the extension exposes a focused subset via the Debug Adapter Protocol (DAP).
The authoritative reference is the Feature Matrix. It lists every feature, which surface supports it, and any relevant limitations.
Key asymmetries at a glance:
- CLI-only features: instruction-level stepping (
--instruction-debug,--step-instructions,--step-mode), storage filters (--storage-filter), auth tree display (--show-auth), batch execution (--batch-args,--repeat), remote client mode (soroban-debug remote), TLS configuration, storage export (--export-storage), event filtering (--show-events,--event-filter), dry-run mode (--dry-run), cross-contract mocking (--mock), and all analysis subcommands (analyze,symbolic,optimize,profile,compare,replay,upgrade-check,scenario,tui,repl). - Extension-only features: hover evaluation (expression evaluation on mouse-hover while paused).
- Shared features: function breakpoints, step in/over/out, continue, call stack inspection, variable and storage inspection when paused, expression evaluation in the Debug Console.
Which surface to use:
- Use the VS Code extension for a visual IDE experience: set breakpoints by clicking, inspect variables in the sidebar, navigate the call stack with keyboard shortcuts.
- Use the CLI for full debugging power: instruction-level stepping, storage filtering, auth analysis, batch runs, remote/CI scenarios, and any of the analysis subcommands.
Cause: Storage filtering via --storage-filter is not exposed in the extension's launch configuration. All storage keys are shown unfiltered in the Variables panel.
Workaround: Either run soroban-debug run --storage-filter '<pattern>' from the terminal to get a targeted view, or use snapshotPath in launch.json to provide a pre-filtered initial storage state. See the Feature Matrix — Storage Filters for details.
Cause: The VS Code extension only connects to a debug server it spawns locally as a subprocess. The soroban-debug remote client mode is not exposed through the extension.
Workaround: Use an SSH tunnel to bridge the remote server to your local machine:
# On the remote machine
soroban-debug server --host 127.0.0.1 --port 9229 --token $MY_TOKEN
# On your local machine (in a separate terminal)
ssh -L 9229:localhost:9229 user@remote-hostThen set "port": 9229 and "token": "$MY_TOKEN" in your launch.json. The extension will connect to the tunnel as if the server were local.
For full remote debugging documentation, see Remote Debugging and the Feature Matrix — Remote Debugging.
Cause: soroban-debug appends one record per run invocation. Without a configured limit the history file grows indefinitely.
Fix: Use the global --history-max-records flag (or its environment variable) to cap how many records are kept:
# Keep only the 100 most-recent runs
soroban-debug --history-max-records 100 run --contract my.wasm --function increment
# Use the env var for a persistent per-shell default
export SOROBAN_DEBUG_HISTORY_MAX_RECORDS=100
soroban-debug run --contract my.wasm --function incrementThe pruning happens atomically during the append — the same tmp-file-rename mechanism that prevents corruption on normal writes.
Use --history-max-age-days (or SOROBAN_DEBUG_HISTORY_MAX_AGE_DAYS):
# Drop runs older than 30 days on every append
soroban-debug --history-max-age-days 30 run --contract my.wasm --function increment
# Persist the policy in the environment
export SOROBAN_DEBUG_HISTORY_MAX_AGE_DAYS=30Both constraints can be combined — the stricter one wins:
# Keep at most 50 records AND discard anything older than 14 days
soroban-debug \
--history-max-records 50 \
--history-max-age-days 14 \
run --contract my.wasm --function incrementUse the history-prune subcommand:
# Prune to the 200 most-recent records
soroban-debug history-prune --max-records 200
# Drop records older than 30 days
soroban-debug history-prune --max-age-days 30
# Combine: keep newest 200 and drop anything older than 30 days
soroban-debug history-prune --max-records 200 --max-age-days 30Dry-run mode — preview what would be removed without writing any changes:
soroban-debug history-prune --max-records 50 --dry-run
# [dry-run] Would remove 143 record(s), 50 would remain.The subcommand also honours the global --history-file flag:
soroban-debug --history-file /path/to/custom-history.json history-prune --max-records 100The newest N records (by their parsed date field, sorted chronologically) are kept; the oldest are removed. This preserves deterministic ordering for --budget-trend regression analysis.
Records whose date field cannot be parsed are kept rather than silently dropped, to avoid data loss from formatting differences.
The Soroban Debugger provides standardized remediation hints for most common failures. When an error like an incorrect WASM path or a bad port connection occurs, the debugger will print an actionable diagnostic:
Example:
× Network/transport error: Failed to connect to 127.0.0.1:9000: Connection refused (os error 61)
help: Action: Ensure the remote debug server is online, address is correct, and network firewall permits the connection.
Context: The transport connection failed to establish or dropped unexpectedly.
If you specify --json or set SOROBAN_DEBUG_JSON=1, these hints are also securely placed inside a machine-readable "hints" array on the output block, allowing your scripts or testing wrappers to automatically process validation suggestions.
{
"status": "error",
"errors": [
"Authentication failed: Invalid security token"
],
"hints": [
"Action: Ensure the shared security token matches the server, and the transport protocol is correct.\nContext: The server rejected communication because authentication wasn't verified."
]
}Answer: These are often caused by environment restrictions in sandboxed CI runners or missing permissions for temp directories. Fix: See the Local and CI Sandbox Failures section in the troubleshooting guide for a matrix of common failures and their fixes.