diff --git a/src/ska/logging/transactions.py b/src/ska/logging/transactions.py
index 7aa6a2eda9c3448529533bafd6eff3fffde31302..43e9572a7e4aabbab0ef99eb6f9282ad89340b4a 100644
--- a/src/ska/logging/transactions.py
+++ b/src/ska/logging/transactions.py
@@ -5,7 +5,7 @@ import json
 import logging
 import os
 
-from typing import Text
+from typing import Mapping, Text
 
 from ska.skuid.client import SkuidClient
 
@@ -13,48 +13,48 @@ from ska.skuid.client import SkuidClient
 class Transaction:
     """Transaction context handler.
 
-     Provides:
-     - Transaction ID:
-       - Re-use existing transaction ID, if available
-       - If no transaction ID, or empty or None, then generate a new ID
-       - context handler returns the transaction ID used
-     - Log messages on entry, exit, and exception
-
-     .. Examples::
-
-        def command(self, parameter_json):
-            parameters = json.reads(parameter_json)
-            with ska.logging.transaction('My Command', parameters) as transaction_id:
-                # ...
-                parameters['transaction_id'] = transaction_id
-                device.further_command(json.dumps(pars))
-                # ...
-
-        def command(self, parameter_json):
-            parameters = json.reads(parameter_json)
-            with ska.logging.transaction('My Command', parameters, transaction_id="123") as transaction_id:
-                # ...
-                parameters['transaction_id'] = transaction_id
-                device.further_command(json.dumps(pars))
-                # ...
-
-        def command(self, parameter_json):
-            parameters = json.reads(parameter_json)
-            parameters["txn_id_key"] = 123
-            with ska.logging.transaction('My Command', parameters, transaction_id_key="txn_id_key") as transaction_id:
-                # ...
-                parameters['transaction_id'] = transaction_id
-                device.further_command(json.dumps(pars))
-                # ...
-
-     Log message formats:
-        On Entry:
-            Transaction [id]: Enter [name] with parameters [arguments]
-        On Exit:
-            Transaction [id]: Exit [name]
-        On exception:
-            Transaction [id]: Exception [name]
-            Stacktrace
+    Provides:
+    - Transaction ID:
+      - Re-use existing transaction ID, if available
+      - If no transaction ID, or empty or None, then generate a new ID
+      - context handler returns the transaction ID used
+    - Log messages on entry, exit, and exception
+
+    .. Examples::
+
+       def command(self, parameter_json):
+           parameters = json.reads(parameter_json)
+           with ska.logging.transaction('My Command', parameters) as transaction_id:
+               # ...
+               parameters['transaction_id'] = transaction_id
+               device.further_command(json.dumps(pars))
+               # ...
+
+       def command(self, parameter_json):
+           parameters = json.reads(parameter_json)
+           with ska.logging.transaction('My Command', parameters, transaction_id="123") as transaction_id:
+               # ...
+               parameters['transaction_id'] = transaction_id
+               device.further_command(json.dumps(pars))
+               # ...
+
+       def command(self, parameter_json):
+           parameters = json.reads(parameter_json)
+           parameters["txn_id_key"] = 123
+           with ska.logging.transaction('My Command', parameters, transaction_id_key="txn_id_key") as transaction_id:
+               # ...
+               parameters['transaction_id'] = transaction_id
+               device.further_command(json.dumps(pars))
+               # ...
+
+    Log message formats:
+       On Entry:
+           Transaction [id]: Enter [name] with parameters [arguments]
+       On Exit:
+           Transaction [id]: Exit [name]
+       On exception:
+           Transaction [id]: Exception [name]
+           Stacktrace
     """
 
     def __init__(
@@ -64,15 +64,15 @@ class Transaction:
         transaction_id: str = "",
         transaction_id_key: str = "transaction_id",
     ):
+        if not isinstance(params, Mapping):
+            raise TransactionParamsError("params must be dict-like (Mapping)")
         # Get the root logger
         self.logger = logging.getLogger()
         self._name = name
         self._params = params
         self._transaction_id_key = transaction_id_key
 
-        self._transaction_id = (
-            transaction_id if self._is_valid_id(transaction_id) else ""
-        )
+        self._transaction_id = transaction_id if self._is_valid_id(transaction_id) else ""
 
         if not self._transaction_id:
             self._transaction_id = self._get_from_params_or_generate_new_id()
@@ -94,9 +94,7 @@ class Transaction:
 
     def __exit__(self, exc_type, exc_val, exc_tb):
         if exc_type:
-            self.logger.exception(
-                f"Transaction[{self._transaction_id}]: Exception[{self._name}]"
-            )
+            self.logger.exception(f"Transaction[{self._transaction_id}]: Exception[{self._name}]")
 
         self.logger.info(f"Transaction[{self._transaction_id}]: Exit[{self._name}]")
 
@@ -161,3 +159,7 @@ class TransactionIdGenerator:
 
     def next(self):
         return self._get_id()
+
+
+class TransactionParamsError(TypeError):
+    """Invalid data type for transaction parameters."""