a9script

Docs / Agents: CLI, MCP, skill

Debugging — the trace, and holding the wheel

Two tools, both sandbox only, both meant for exactly the position you are in: something is wrong and nobody is watching the screen.

The trace: what actually left the platform

A run started with --debug keeps every outbound call — the request as sent and every attempt back, headers and bodies included:

a9script run sync-contact --input _input.json --debug --json
a9script history <run> --json
a9script inspect <run> 1 --json
  • history lists the calls: name, connection, status, attempts, verdict, duration. It never carries a body. Its nextActions points at the call worth opening — the first that did not answer, else the last one made.
  • inspect <run> <seq> is that call whole. The credential is NAMED, never valued: you can see that a bearer token was attached without seeing it.
  • A body over the trace’s ceiling is cut, and says so with a truncated mark. A cut body is not the far end’s last word — do not read the end of one as the end of the response.

Read the response before you change the script. Most integration failures are a far end explaining itself in a body nobody looked at: an id format, a required field, a scope the credential does not have. Your run’s error is your script’s view of the failure; the trace is the far end’s.

Two refusals worth recognising:

  • NOT_A_DEBUG_RUN — that run kept no trace. Re-run it with --debug.
  • TRACE_EXPIRED — traces are short-lived by design; that run is too old. Re-run it with --debug for a fresh one. It does NOT mean the run made no calls.

Debug is refused outside a sandbox (DEBUG_REQUIRES_SANDBOX) — a debug run keeps payloads, which is not something production traffic may do.

Stepping: one external call at a time

--step runs a script that pauses after every call that leaves the platform — a configured HTTP call, a model prompt, a mail send — and waits for you. It implies --debug, because a pause you cannot look into is theatre.

a9script run place-order --input _input.json --step --json

The command exits 0 with the run PARKED: starting the session is what you asked for. From there:

commandwhat it does
a9script sessionsevery paused run in this environment
a9script position <run>the parked call, the statement, the variables in scope
a9script continue <run>let exactly one more external call happen
a9script continue <run> --to-endstop stepping; finish as an ordinary debug run
a9script abort <run>stop here — nothing further is sent

A session id IS the run’s id. Nothing is stored on your side, so a fresh shell picks up a session with sessions.

What position tells you. Whether the parked call has already been made (its answer recorded) or is still waiting to fire; which statement the script is on; and the variables in scope with type-faithful previews — "", null, undefined and “declared but not yet assigned” are four different findings and they look different. Large values are summarised rather than dumped.

Use it for the destructive middle of a new write path. The first time a script creates, updates or deletes at a far end, step it: check the arguments at the pause, continue if they are right, abort if they are not — an aborted session sends nothing further, and the far end saw only the calls you allowed.

Once the path is proven, run it normally. Stepping is a debugging posture, not a deployment one — nothing dispatched by a trigger is ever stepped.

A session does not wait forever. Left untouched it expires, and the verbs then answer STEP_EXPIRED rather than pretending it is still there. Other refusals in the same family:

  • NOT_A_STEPPED_RUN — that run was not started with --step. In particular, a run waiting because the far end asked it to wait is not a stepped session, and continue will not cut that wait short.
  • RUN_NOT_PAUSED — the run is not paused; the message says what it is now (it may have finished, or another command may already have ended it).
  • STEP_REQUIRES_SANDBOX — same reason as --debug.

continue answers what actually HAPPENED, not what was asked: resumed (a step is running), waiting (the run is parked on a far end’s own wait — nothing changed), or executing (a step is running right now; ask again with position).

Which one to reach for

  • The run failed and you want to know why → --debug, then history and inspect.
  • The run is going to write something and you want a say in whether it does → --step.
  • You want the shape of one call and no script is involved → a9script probe (config functions).
Rendered from docs/skills/a9script-authoring/reference/debugging.md in the product's own repository, at build time. Found a problem on this page? Write to the address in the footer.