Error Handling
openocd-python uses a structured exception hierarchy rooted at OpenOCDError. Every exception the library raises is a subclass of this base, so you can catch broadly or narrowly depending on your needs.
Exception hierarchy
Section titled “Exception hierarchy”OpenOCDError├── ConnectionError # TCP connection failures├── TimeoutError # Deadline exceeded├── TargetError # Target not responding or returned an error│ └── TargetNotHaltedError # Operation requires halted target├── FlashError # Flash operation failed├── JTAGError # JTAG communication error├── SVDError # SVD file or parsing error├── ProcessError # OpenOCD subprocess failed└── BreakpointError # Breakpoint/watchpoint operation failedAll exceptions are importable from the top-level openocd package:
from openocd import ( OpenOCDError, ConnectionError, TimeoutError, TargetError, TargetNotHaltedError, FlashError, JTAGError, SVDError, ProcessError,)Exception details
Section titled “Exception details”OpenOCDError
Section titled “OpenOCDError”The base class for all library exceptions. Catching this handles any error that openocd-python can raise:
from openocd import OpenOCDError, Session
with Session.connect_sync() as ocd: try: state = ocd.target.state() except OpenOCDError as e: print(f"Something went wrong: {e}")ConnectionError
Section titled “ConnectionError”Raised when a TCP connection to OpenOCD cannot be established. Common causes:
- OpenOCD is not running
- Wrong host or port
- Firewall blocking the connection
- Network unreachable
from openocd import ConnectionError, Session
try: with Session.connect_sync(host="192.168.1.99", port=6666) as ocd: ocd.target.state()except ConnectionError as e: print(f"Cannot reach OpenOCD: {e}")Also raised if a command is sent after the connection has been closed, or if OpenOCD closes the connection unexpectedly during a read.
TimeoutError
Section titled “TimeoutError”Raised when an operation exceeds its deadline. This can happen during:
- Initial connection (
Session.connect()withtimeoutparameter) - Waiting for OpenOCD to start (
Session.start()withtimeoutparameter) - Individual command responses (the
TclRpcConnectiontimeout) target.wait_halt()when the target does not halt in time
from openocd import TimeoutError, Session
with Session.connect_sync() as ocd: try: # Wait up to 2 seconds for the target to halt ocd.target.wait_halt(timeout_ms=2000) except TimeoutError: print("Target did not halt within 2 seconds")TargetError
Section titled “TargetError”Raised when a target command fails. The error message contains the raw OpenOCD response for diagnosis. This covers halt, resume, step, reset, memory read/write, and register access failures.
from openocd import TargetError, Session
with Session.connect_sync() as ocd: try: ocd.target.halt() except TargetError as e: print(f"Target command failed: {e}")TargetNotHaltedError
Section titled “TargetNotHaltedError”A subclass of TargetError, raised specifically when an operation requires a halted target but the target is running. This is most commonly encountered when reading or writing registers.
from openocd import TargetNotHaltedError, Session
with Session.connect_sync() as ocd: try: pc = ocd.registers.pc() except TargetNotHaltedError: print("Halt the target first before reading registers") ocd.target.halt() pc = ocd.registers.pc()Because TargetNotHaltedError is a subclass of TargetError, catching TargetError will also catch it:
try: pc = ocd.registers.pc()except TargetNotHaltedError: # Handle the specific case ocd.target.halt() pc = ocd.registers.pc()except TargetError: # Handle other target errors print("Unexpected target error")FlashError
Section titled “FlashError”Raised when a flash operation fails — programming, erasing, verifying, or reading flash memory. The error message includes the raw OpenOCD response.
from openocd import FlashError, Sessionfrom pathlib import Path
with Session.connect_sync() as ocd: try: ocd.flash.write_image(Path("firmware.bin")) except FlashError as e: print(f"Flash programming failed: {e}")Also raised for:
- Invalid sector ranges (e.g.,
first > lastinerase_sector) - Verification mismatches after
write_imagewithverify=True - Unparseable flash info output
JTAGError
Section titled “JTAGError”Raised when JTAG communication fails. This covers chain scan errors, TAP state transitions, and raw scan operations.
from openocd import JTAGError, Session
with Session.connect_sync() as ocd: try: taps = ocd.jtag.scan_chain() except JTAGError as e: print(f"JTAG error: {e}")SVDError
Section titled “SVDError”Raised when SVD-related operations fail:
- SVD file not found or cannot be parsed
- Peripheral name not found in the loaded SVD
- Register name not found within a peripheral
- No SVD file loaded when trying to list or decode
from openocd import SVDError, Sessionfrom pathlib import Path
with Session.connect_sync() as ocd: try: ocd.svd.load(Path("nonexistent.svd")) except SVDError as e: print(f"SVD error: {e}")ProcessError
Section titled “ProcessError”Raised when the OpenOCD subprocess fails to start or exits unexpectedly. This only applies when using Session.start().
from openocd import ProcessError, Session
try: with Session.start_sync("nonexistent_config.cfg") as ocd: passexcept ProcessError as e: print(f"OpenOCD failed to start: {e}")Common causes:
- OpenOCD binary not found on
PATH - Invalid configuration file
- OpenOCD exits before the TCL RPC port is ready
- Permission errors
BreakpointError
Section titled “BreakpointError”Raised when a breakpoint or watchpoint operation fails. Defined in openocd.breakpoints but inherits from OpenOCDError.
from openocd.breakpoints import BreakpointErrorfrom openocd import Session
with Session.connect_sync() as ocd: try: ocd.breakpoints.add(0x08001234, length=2, hw=True) except BreakpointError as e: print(f"Breakpoint error: {e}")Catching patterns
Section titled “Catching patterns”Broad catch — handle any library error
Section titled “Broad catch — handle any library error”from openocd import OpenOCDError, Session
with Session.connect_sync() as ocd: try: ocd.target.halt() pc = ocd.registers.pc() data = ocd.memory.read_u32(pc, count=4) except OpenOCDError as e: print(f"Operation failed: {e}")Narrow catch — handle specific failure modes
Section titled “Narrow catch — handle specific failure modes”from openocd import ( Session, ConnectionError, TargetError, TargetNotHaltedError, TimeoutError,)
try: with Session.connect_sync() as ocd: ocd.target.halt() pc = ocd.registers.pc() ocd.target.resume()except ConnectionError: print("Could not connect to OpenOCD")except TargetNotHaltedError: print("Target is not halted")except TimeoutError: print("Operation timed out")except TargetError as e: print(f"Target error: {e}")Retry pattern
Section titled “Retry pattern”from openocd import Session, TimeoutError
with Session.connect_sync() as ocd: for attempt in range(3): try: ocd.target.halt() ocd.target.wait_halt(timeout_ms=1000) break except TimeoutError: if attempt == 2: raise print(f"Attempt {attempt + 1} timed out, retrying...") ocd.target.reset(mode="halt")Recovery from TargetNotHaltedError
Section titled “Recovery from TargetNotHaltedError”A common pattern is to attempt a register read and automatically halt if needed:
from openocd import Session, TargetNotHaltedError
def safe_read_pc(ocd) -> int: try: return ocd.registers.pc() except TargetNotHaltedError: ocd.target.halt() return ocd.registers.pc()
with Session.connect_sync() as ocd: pc = safe_read_pc(ocd) print(f"PC = 0x{pc:08X}")Error responses from OpenOCD
Section titled “Error responses from OpenOCD”Internally, most subsystems detect errors by checking for the word “error” in the OpenOCD response string. This is because OpenOCD’s TCL RPC protocol does not use structured error codes — all errors are communicated as plain text in the response body.
The library wraps these text responses in the appropriate exception type so you do not need to parse them yourself. The original OpenOCD message is preserved in the exception’s string representation.
Next steps
Section titled “Next steps”- Target Control — which methods raise which exceptions
- Memory Operations — error handling for memory reads and writes
- Session Lifecycle — connection and process errors