
antithesis-debug
Run a bash script inside an Antithesis run at a chosen moment with snouty runs exec, from the terminal and without a browser. Use it for scripted forensics on a run: process and container inspection, on-disk evidence, gdb attach, and general debugging. Covers command usage, the live-session requirement, common workflows and errors, and how virtual time and perturbation limit what a debugger can see.
- Installs
- 567
- Last 24h
- +9
- Trending rank
- #8974
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/antithesishq/antithesis-skills --skill antithesis-debug- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads antithesis-debug automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Antithesis Debug
Skill version: 2026-10-21 4f8d80b
Execute a bash script at a moment in a run. Each call branches the multiverse and repeated calls from the same moment reproduce. Can use a currently running run or an active MVD session.
When to use this skill
- The user gives you Antithesis debugging-session run ID or URL
- The user asks you to debug or investigate a failing property, bug, or any result from a past run
- The user makes a request to inspect container filesystem, runtime state, or events inside Antithesis
- Triage suggested this skill because logs alone haven't explained a failure
Failed property warning
Commands run with runs exec on a live run can trigger a run's assertions, which will result in a failing property that looks exactly like a real bug.
Use a debugging session if you want to avoid these kinds of false positives. Preference using a currently running run for speed, ease of use, and less core hours for commands you do not think will cause this problem.
Prerequisites
- DO NOT PROCEED if
snoutyis not installed. Seehttps://raw.githubusercontent.com/antithesishq/snouty/refs/heads/main/README.mdfor installation options. - DO NOT PROCEED if
snoutyis older than 0.8.0, the first release whereruns execis stable. Usesnouty --versionto find the version. Usesnouty updateto update. - You must have a session from a live run or MVD session to use this command. See get a live session first for more info.
- You must be logged into an Antithesis tenant from snouty. Run
snouty doctorto confirm. Ask your user to log you in or use an API key if you are not logged in.
Get a live session first
-
execneeds a live session. A session can either be tied to a run or MVD session. In snouty both runs and debugging sessions show as runs. -
A run holds one while it runs, and for a short time after it ends. It will work a few minutes after completion but not hours.
-
To see if a run has an active session use:
snouty --json runs show <run> | jq -r '[.status, .sub_status // empty] | join(":") | ascii_downcase'This prints the status and the sub-status together.
in_progress:readymeans you can run commands against the run.in_progresswith any other sub-status, such asin_progress:loading, means the session is still loading.snouty runs wait <run> --until readyreturns once the run is ready to use, or once it has already finished. It prints the status it stopped at, so check that it isin_progress:readybefore you exec. -
If the user gives a debugging-session URL, that session may already be running. Find its run ID among the sessions, matching on title, description or creation time.
runs listshows only the status, so pick anin_progresssession, then check thatruns showreports itin_progress:ready:snouty --json runs list --launcher debugging \ | jq -c '{run_id, status, created_at, title: .parameters["antithesis.test_name"], source_run: .parameters["antithesis.debugging.run_id"]}'source_runis the value to pass to--source-run-id. -
For an older run, make a debugging session first:
snouty debug --run-id <run> --input-hash <hash> --vtime <vtime> \ --title "Counter property failure 2026-10-13"- Always pass a
--titlethat is unique and easy to find later, for example the property name plus a date or ticket id. It is the namesnouty runs listshows for the session. Add--descriptiononly if the reason won't fit in the title.--recipientstakes semicolon-separated emails to notify. - This returns a new run ID. Wait with
snouty runs wait <new run ID> --until ready, thenexecagainst it. - Use
--source-run-id <run>for the first command because the moment isn't warm yet. With the source, the call blocks and prints rewarming moment: N% until the moment is ready. - Expect 2 to 20 minutes from snouty debug to the first successful exec: a few minutes of 404s while the session loads, then a rewarm that takes longer the later the moment's vtime. After that, the moment is warm and later commands on that moment don't need the source.
- If exec answers 404 or "Moment not warm", the session is still loading. Retry. Look at get a moment to find the right input-hash and vtime for your users request.
- Always pass a
Get a moment (input hash and vtime)
input-hash and vtime pin the single moment to debug. Extract the input hash and vtime from context and pass them to the command.
If the user didn't give you a moment, read references/moments.md for where to find one.
If you can't pin down both an input hash and a vtime from a clear source, ask the user rather than guessing.
To find a moment (input hash + vtime) from a failing or passing property, or
from a log line, query for it with snouty runs search (see step 3 of the
example workflow).
Required input
-
RUN_IDis a live run, or a debugging session's run id. -
INPUT_HASHandVTIMEare a moment from that run, taken together as a pair from one event thatsnouty runs searchreturns. -
INPUT_HASHis often negative, for example-1520695250096255483. Pass it as-is: snouty reads it as the hash, not as a flag, so you don't need--. Adding--turns every flag after it into a positional argument and breaks the command.snouty runs exec "$RUN_ID" -1520695250096255483 67.7622960046865 'uptime' -
SCRIPTis the bash to run. Pass it as the last argument, or omit it and pipe it in, for example < script.sh.
Optional flags
--timeout DURATIONis how long the server waits for the script to exit. It takes units:90s,5m,1h. A bare number means seconds. The default is 10m (as of release 64.0). Rewarming a cold moment does not count against it.--container NAMEruns the script inside that container. Without it, the script runs on the host.--source-run-id IDnames the run a cold moment comes from. When the target is a debugging session, this is the run you opened the session from, not the session id. Use this flag on your first command after starting a debugging session.--source-session-id IDis the session alternative to--source-run-id. You can't use both.--eventsstreams every event on the timeline while the script runs, not just the script's output.--jsonprints machine-readable json output.
Execution Tips
-
Use
--containerover podman exec inside the script to run a command on a single container. -
--containerneeds a container name, and works only on Docker Compose tests (see Kubernetes tests below). If you've already runsnouty runs searchorsnouty runs logs, take the name from any container log event'ssource.container. Otherwise, list them by running this once without--container, so it runs on the host:snouty runs exec "$TARGET" "$HASH" "$VTIME" 'podman ps -a --format "{{.Names}} {{.Status}}"'On a Docker Compose test, names are the same at every moment of a run, so list them once.
-
--containerworks only on a container that is running at your moment. If it crashed or exited earlier,podman ps -ashows it asExited, and--containerfails. Exec from an earlier moment when it was still up. Find one withsnouty runs searchon that container's last log lines. -
Don't use
--containerand run on host, if you need a snapshot across multiple containers. -
To get a file out of the run, print it to stdout and redirect locally:
# text snouty runs exec "$TARGET" "$HASH" "$VTIME" --container app 'cat /var/log/app.log' > app.log # binary or a directory: tar + base64, then decode locally snouty runs exec "$TARGET" "$HASH" "$VTIME" --container app \ 'tar czf - /data/db | base64' | base64 -d > db.tgz
Kubernetes tests
--container doesn't work on a Kubernetes test (the launcher in snouty runs show
contains "Kubernetes" or "k8s"). Leave it out and read references/kubernetes.md.
Run a Script from a File
-
For anything longer than one line, write the script to a file and redirect it in:
cat > script.sh <<'EOF' echo "host: $(hostname)" ps aux EOF snouty runs exec "$RUN_ID" "$INPUT_HASH" "$VTIME" < script.shThe quotes around
'EOF'keep$(hostname)from running on your machine on accident. -
Reuse one script across moments. Run the same file at several moments and compare the outputs.
-
Save output to a file named after the moment.
-
Always save --events output to a file. The stream is long, so grep the file afterwards:
snouty runs exec --events $RUN $HASH $VTIME < oracle.sh > out.txt grep -E "FAIL|HIT|exit" out.txt
Picking a Timeout and Timing
- Size
--timeoutto the script alone. A cold moment is rewarmed first, which can take minutes (longer the later the moment's vtime), but that time doesn't count against--timeout. Raise it only for slow scripts, for example--timeout 30m. - A timeout doesn't mean the script didn't run. Search the run for its output (
snouty runs search) before re-running anything that changes state. - Your script advances virtual time. Keep snapshots short. Take one query at the right moment rather than polling, because polling can change the timing you're trying to observe.
- The same command from the same moment gives the same branch. Repeating it doesn't sample new timings.
- After one exec with a source succeeds, that moment stays warm in the session. Later commands there need no source and return quickly.
- Earlier moments on the session's own timeline are warm too, so they need no rewarm.
Rewarm progress
A cold moment shows progress while it rewarms. By default the command prints rewarming moment: N% lines on stderr. With --json, it prints {"status":"rewarming","percent_complete":N} frames on stdout, ahead of the script's output.
- A rising percentage means the rewarm is working. Don't retry or cancel while it climbs.
- The percentage can stay at 0% for several minutes and then jump to near 100%. A stall at 0% is not a failure. Leave the call running.
Cancel when done
Runs and debugging sessions use core hours until they end. A debugging session doesn't end when you stop using it: by default it expires only after 6 hours. Cancel any session you opened as soon as you no longer need it, or won't need it soon:
snouty runs cancel "$TARGET"
- Ask a user before canceling a session. They may want to continue to use it for another debugging session when you are done.
- Make sure you are completely done with a run or debugging session before canceling, as if you want to run more commands you will have to wait for a new session to get setup.
- Don't cancel a run you didn't open unless the user asks.
Example Workflow
1. Prerequisites
snouty --version # 0.8.0 or newer
2. Get a session
RUN=<run_id>
snouty --json runs show "$RUN" | jq -r '[.status, .sub_status // empty] | join(":") | ascii_downcase'
-
in_progress:ready: use the run itself.TARGET="$RUN". -
starting, orin_progresswith another sub-status: wait withsnouty runs wait "$RUN" --until ready, then use the run if the status it prints isin_progress:ready. -
Otherwise: pick a moment (step 3), then open a session at it and wait for it. Retry exec on 404 or "Moment not warm" while it loads.
snouty debug --run-id "$RUN" --input-hash "$HASH" --vtime "$VTIME" --title "<property> <date>" TARGET=<runId from the output> snouty runs wait "$TARGET" --until ready
3. Pick a moment
Find moments with snouty runs search, and query for exactly the events you want. For example, the failing evaluations of one property:
snouty --json runs search "$RUN" \
'filter(ev => ev.antithesis_assert?.hit
&& ev.antithesis_assert.id == "<property name>"
&& !ev.antithesis_assert.condition)' \
| jq -r '.moment | "\(.input_hash) \(.vtime)"'
Drop the ! for passing evaluations. To find a log line, use contains({output_text: "<error text>"}). To find an assertion by its message, use filter(ev => ev.antithesis_assert?.message?.includes("<message text>")). Assertions have no output_text, so the log-line query won't find them. See references/moments.md.
runs search returns at most 50 results by default. Add --limit 999 if you need more than a few.
4. Exec
Use --source-run-id for the first command after starting a session because the moment is still warming up. After that, the moment is warm and later commands don't need the source unless you change the moment.
cat > probe.sh <<'EOF'
hostname
ps aux | head -20
EOF
snouty runs exec "$TARGET" "$HASH" "$VTIME" --source-run-id "$RUN" < probe.sh > out.txt
5. Use the results
Apply the output to the user's goal, usually finding the cause of a bug. If the
output doesn't answer the question, exec again at an earlier moment, or from the
end moment line to continue forward.
If necessary give the user the moment, the script, and the relevant output, so they can rerun it.
6. Cancel
If you opened a session, ask a user if they want you to cancel the run once you are done running commands. Otherwise it keeps using core hours until it expires after 6 hours:
snouty runs cancel "$TARGET"
gdb
To inspect a process with gdb, read references/gdb.md.
Virtual time
Before choosing a moment or probing a transient event, read
references/virtual-time.md.
If the earlier moment isn't warm, add --source-run-id.
Common Errors
If exec returns an error, read references/errors.md.
Self-Review
Before reporting back, check your work against these criteria:
- Every finding comes from actual
execoutput, not inferred or assumed. - The evidence chain is clear: the moment (input hash and vtime), the script, what it returned, and what follows from it.
- The summary separates what the output shows from what you interpret or recommend.
- You've asked the user if you should cancel any debugging session you opened, or the user knows it is still running.
Known issues
execcan still return 404 for several minutes aftersnouty runs wait --until readyreturns. Keep retrying; the session is still loading.- After
snouty runs cancel, the run's status may showcompletedinstead ofcancelled. The cancel worked.
FAQ
What does the antithesis-debug skill do?
Run a bash script inside an Antithesis run at a chosen moment with snouty runs exec, from the terminal and without a browser. Use it for scripted forensics on a run: process and container inspection, on-disk evidence, gdb attach, and general debugging. Covers command usage, the live-session requirement, common workflows and errors, and how virtual time and perturbation limit what a debugger can see.
How do I install antithesis-debug?
Run npx skills add https://github.com/antithesishq/antithesis-skills --skill antithesis-debug in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/antithesis-debug/ (personal) or .claude/skills/antithesis-debug/ (project).
Which AI agents can use antithesis-debug?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is antithesis-debug safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains antithesis-debug?
It is published by antithesishq in antithesishq/antithesis-skills, and it is an official skill from the maker of the technology it covers. It has 567 recorded installs.
More from antithesishq/antithesis-skills
antithesis-research
antithesishq/antithesis-skills
Analyze a codebase to figure out how it should be tested with Antithesis: map the system, identify failure-prone areas and testable properties, and produce the research artifacts needed for workload and environment planning.
antithesis-documentation
antithesishq/antithesis-skills
Use Antithesis documentation efficiently for product, workflow, and integration questions. Prefer the snouty docs CLI when available, and otherwise request markdown versions of documentation pages directly.
antithesis-triage
antithesishq/antithesis-skills
Triage Antithesis test reports to understand what happened in a run: look up runs, check status, investigate failed properties (assertions), view metadata, download logs, search events across all timelines, inspect findings, and examine environmental details. Load after a run completes or when investigating a failure.
antithesis-workload
antithesishq/antithesis-skills
Implement Antithesis workloads by turning the property catalog into SDK assertions and test commands, then refine coverage after triage.
antithesis-setup
antithesishq/antithesis-skills
Scaffold the Antithesis harness with docker-compose: initialize the working directory, write Dockerfiles and docker-compose.yaml with build directives, and prepare to submit your first Antithesis test run. If the desired setup is Kubernetes, defer to the antithesis-setup-k8s skill.
antithesis-launch
antithesishq/antithesis-skills
Launch an Antithesis run with snouty by discovering the harness layout, building the right Docker Compose config, running snouty validate, bailing on validation failure, and then submitting snouty launch with sane metadata. Use when the user wants to send, submit, or launch an Antithesis run. This skill takes duration in minutes as input.
Popular code quality & workflow skills
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
improve-codebase-architecture
mattpocock/skills
Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
handoff
mattpocock/skills
Compact the current conversation into a handoff document for another agent to pick up.
domain-modeling
mattpocock/skills
Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR.
codebase-design
mattpocock/skills
Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.
diagnosing-bugs
mattpocock/skills
Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.