{"record":{"id":"49ce66ef7516c598","repo":"NationalSecurityAgency/ghidra","slug":"no-transaction-49ce66","errorCode":null,"errorMessage":"No transaction","messagePattern":"No transaction","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/rmi/jpda/JdiCommands.java","lineNumber":102,"sourceCode":"\t\t\tthrow new RuntimeException(\"No trace started\");\n\t\t}\n\t\treturn trace;\n\t}\n\n\tpublic void requireNoTrace() {\n\t\tif (trace != null) {\n\t\t\tthrow new RuntimeException(\"Trace already started\");\n\t\t}\n\t}\n\n\tpublic void resetTrace() {\n\t\ttrace = null;\n\t\tresetTx();\n\t}\n\n\tpublic RmiTransaction requireTx() {\n\t\tif (tx == null) {\n\t\t\tthrow new RuntimeException(\"No transaction\");\n\t\t}\n\t\treturn tx;\n\t}\n\n\tpublic void requireNoTx() {\n\t\tif (tx != null) {\n\t\t\tthrow new RuntimeException(\"Transaction already started\");\n\t\t}\n\t}\n\n\tpublic void resetTx() {\n\t\ttx = null;\n\t}\n\n}\n\npublic class JdiCommands {\n","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/rmi/jpda/JdiCommands.java#L84-L120","documentation":"RuntimeException('No transaction') thrown by State.requireTx() when the tx field is null. Commands that mutate the trace must do so inside an RmiTransaction; requireTx() ensures one is open. Calling a mutating command outside a started transaction fails here.","triggerScenarios":"Issuing a trace-mutating command that calls requireTx() before a transaction has been started (tx is null), or after the transaction was committed/reset (resetTx sets tx=null).","commonSituations":"Command sequence that skips the start-transaction step; transaction was ended/reset and mutations continued; a long script whose transaction timed out or was committed mid-flow.","solutions":["Start a transaction (the start-tx command) before issuing mutating trace commands.","Guard by checking state.tx != null before mutating, or catch RuntimeException.","After commit/reset, open a new transaction before further mutations."],"exampleFix":"// before\nstate.requireTx().mutate(...);\n\n// after\nif (state.tx == null) {\n    throw new IllegalStateException(\"Open a transaction before mutating the trace\");\n}\nstate.requireTx().mutate(...);","handlingStrategy":"validation","validationCode":"if (state.tx == null) {\n    throw new IllegalStateException(\"Open a transaction first\");\n}\nstate.requireTx().mutate(...);","typeGuard":null,"tryCatchPattern":"try {\n    state.requireTx();\n} catch (RuntimeException e) {\n    if (\"No transaction\".equals(e.getMessage())) {\n        // start a transaction before mutating\n    }\n}","preventionTips":["Start a transaction before mutating the trace.","Check state.tx != null as a precondition.","Open a new transaction after commit/reset."],"tags":["ghidra","jdi","jpda","transaction","state-machine","validation"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}