NationalSecurityAgency/ghidra · error · RuntimeError
Transaction already started
Error message
Transaction already started
What it means
Raised as RuntimeError by State.require_no_tx() when STATE.tx is already set — a transaction is open and nesting is not allowed. Attempting to open a second transaction before the first closes triggers it.
Source
Thrown at Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py:138
def require_no_trace(self) -> None:
if self.trace != None:
raise RuntimeError("Trace already started")
def reset_trace(self) -> None:
self.trace: Optional[Trace[Extra]] = None
util.set_convenience_variable('_ghidra_tracing', "false")
self.reset_tx()
def require_tx(self) -> Tuple[Trace, Transaction]:
trace = self.require_trace()
if self.tx is None:
raise RuntimeError("No transaction")
return trace, self.tx
def require_no_tx(self) -> None:
if self.tx != None:
raise RuntimeError("Transaction already started")
def reset_tx(self) -> None:
self.tx: Optional[Transaction] = None
STATE = State()
def ghidra_trace_connect(address: Optional[str] = None) -> None:
"""
Connect Python to Ghidra for tracing
Address must be of the form 'host:port'
"""
STATE.require_no_client()
if address is None:
raise RuntimeError(View on GitHub (pinned to d5f144c24d)
Solutions
- Re-use the existing open transaction instead of opening a nested one.
- Guard: if STATE.tx is not None: perform the work in the current tx rather than opening another.
- Ensure earlier open_tx blocks are exited (context manager) before starting a new one.
Example fix
// before
with trace.open_tx('outer'):
with trace.open_tx('inner'): # RuntimeError: Transaction already started
...
// after
with trace.open_tx('outer'):
... # do inner work in the same transaction Defensive patterns
Strategy: validation
Validate before calling
if STATE.tx is not None:
raise RuntimeError('a transaction is already open; reuse it instead of nesting') Type guard
def no_open_transaction() -> bool:
return getattr(STATE, 'tx', None) is None Try / catch
try:
with trace.open_tx('op'):
do_work(trace)
except RuntimeError as e:
if 'Transaction already started' in str(e):
do_work(trace) # reuse the ambient transaction
else:
raise Prevention
- Never nest open_tx() blocks; reuse the ambient transaction.
- Ensure helpers that open their own tx are not called from within an open tx.
- Make sure earlier open_tx blocks exit (context manager) before starting new ones.
When it happens
Trigger: Calling open_tx() (or a helper that opens one) while already inside an open_tx block.
Common situations: Nested open_tx() calls; a helper that opens its own tx invoked from within another tx; a tx left open by an exception.
Related errors
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/63a263d5ec8d00f9.
Report an issue: GitHub.