diff --git a/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py b/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py
index ae00635acf68e059c62faf7a5b8d27a2ca435eec..ee898ff561ea916431a7100f098069c68b4e5a13 100644
--- a/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py
+++ b/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py
@@ -1,6 +1,7 @@
 from operator import mul
 from functools import reduce
 
+import numpy
 from tango.server import attribute
 from tango import AttrWriteType, AttReqType
 
@@ -40,6 +41,21 @@ class attribute_io(object):
     def cached_write_function(self, value):
         """ Writes the given value to the device, and updates the cache. """
 
+        # flexible array sizes are not supported by all clients. make sure we only write arrays of maximum size.
+        if self.attribute_wrapper.shape != ():
+            if isinstance(value, numpy.ndarray):
+                value_shape = value.shape
+            else:
+                if len(value) > 0 and isinstance(value[0], list):
+                    # nested list
+                    value_shape = (len(value), len(value[0]))
+                else:
+                    # straight list
+                    value_shape = (len(value),)
+
+            if value_shape != self.attribute_wrapper.shape:
+                raise ValueError(f"Tried writing an array of shape {value_shape} into an attribute of shape {self.attribute_wrapper.shape}")
+
         self.write_function(value)
         self.cached_value = value
 
@@ -77,20 +93,27 @@ class attribute_wrapper(attribute):
             max_dim_x = 1
             max_dim_y = 0
             dtype = datatype
+            shape = ()
         elif len(dims) == 1:
             max_dim_x = dims[0]
             max_dim_y = 0
             dtype = (datatype,)
+            shape = (max_dim_x,)
         elif len(dims) == 2:
             max_dim_x = dims[1]
             max_dim_y = dims[0]
             dtype = ((datatype,),)
+            shape = (max_dim_y, max_dim_x)
         else:
             # >2D arrays collapse into the X and Y dimensions. The Y (major) dimension mirrors the first dimension given, the
             # rest collapses into the X (minor) dimension.
             max_dim_x = reduce(mul, dims[1:])
             max_dim_y = dims[0]
             dtype = ((datatype,),)
+            shape = (max_dim_y, max_dim_x)
+
+        # actual shape of the data as it is read/written
+        self.shape = shape
 
         if access == AttrWriteType.READ_WRITE:
             """ If the attribute is of READ_WRITE type, assign the write and read functions to it"""
diff --git a/tangostationcontrol/tangostationcontrol/test/clients/test_attr_wrapper.py b/tangostationcontrol/tangostationcontrol/test/clients/test_attr_wrapper.py
index cfc90c25c7b06e61d7e0dca9f67cc0a46daac281..6381db2d7c4cc6e02cf891b761addacfe37064f1 100644
--- a/tangostationcontrol/tangostationcontrol/test/clients/test_attr_wrapper.py
+++ b/tangostationcontrol/tangostationcontrol/test/clients/test_attr_wrapper.py
@@ -39,7 +39,6 @@ def dev_init(device):
         asyncio.run(i.async_set_comm_client(device, device.test_client))
     device.test_client.start()
 
-
 class TestAttributeTypes(base.TestCase):
     def setUp(self):
         # Avoid the device trying to access itself as a client
@@ -491,7 +490,6 @@ class TestAttributeTypes(base.TestCase):
             info = "Test failure in {} {} readback test  \n\tW: {} \n\tRW: {} \n\tR: {}".format(test_type, dtype, val, result_RW, result_R)
             raise Exception(info) from e
 
-
     """
     List of different types to be used with attributes testing, using any other
     might have unexpected results. Each type is bound to a device scalar,
@@ -629,6 +627,9 @@ class TestAttributeAccess(base.TestCase):
         scalar_R = attribute_wrapper(comms_annotation="float32_scalar_R", datatype=numpy.float32)
         scalar_RW = attribute_wrapper(comms_annotation="float32_scalar_RW", datatype=numpy.float32, access=AttrWriteType.READ_WRITE)
 
+        spectrum_RW = attribute_wrapper(comms_annotation="spectrum_RW", dims=(3,), datatype=numpy.float32, access=AttrWriteType.READ_WRITE)
+        image_RW = attribute_wrapper(comms_annotation="image_RW", dims=(3,2), datatype=numpy.float32, access=AttrWriteType.READ_WRITE)
+
         def configure_for_initialise(self):
             dev_init(self)
             self.set_state(DevState.STANDBY)
@@ -643,3 +644,30 @@ class TestAttributeAccess(base.TestCase):
             proxy.initialise()
 
             _ = proxy.scalar_R
+
+    def test_write_correct_dims_spectrum(self):
+        with DeviceTestContext(self.float32_scalar_device, process=True) as proxy:
+            proxy.initialise()
+
+            proxy.spectrum_RW = [1.0, 2.0, 3.0]
+
+    def test_write_wrong_dims_spectrum(self):
+        with DeviceTestContext(self.float32_scalar_device, process=True) as proxy:
+            proxy.initialise()
+
+            with self.assertRaises(DevFailed):
+                proxy.spectrum_RW = [1.0]
+
+    def test_write_correct_dims_image(self):
+        with DeviceTestContext(self.float32_scalar_device, process=True) as proxy:
+            proxy.initialise()
+
+            proxy.image_RW = [[1.0, 2.0], [2.0, 3.0], [3.0, 4.0]]
+
+    def test_write_wrong_dims_image(self):
+        with DeviceTestContext(self.float32_scalar_device, process=True) as proxy:
+            proxy.initialise()
+
+            with self.assertRaises(DevFailed):
+                proxy.image_RW = [[1.0, 2.0], [2.0, 3.0]]
+
diff --git a/tangostationcontrol/tangostationcontrol/test/clients/test_client.py b/tangostationcontrol/tangostationcontrol/test/clients/test_client.py
index 245e03eff42a5592fa3a36673a2d1e01405e680f..4f3a0c5d2eda256bc089ebd58c4dbc587beb08cd 100644
--- a/tangostationcontrol/tangostationcontrol/test/clients/test_client.py
+++ b/tangostationcontrol/tangostationcontrol/test/clients/test_client.py
@@ -23,6 +23,9 @@ class test_client(CommClient):
         """
         super().__init__(fault_func, try_interval)
 
+        # holder for the values of all attributes
+        self.values = {}
+
         # Explicitly connect
         self.connect()
 
@@ -69,26 +72,32 @@ class test_client(CommClient):
 
         return dims, dtype
 
-    def _setup_mapping(self, dims, dtype):
+    def _setup_mapping(self, annotation, dims, dtype):
         """
         takes all gathered data to configure and return the correct read and write functions
         """
+
+        # we emulate that values written to annotations ending in _RW show up in their corresponding _R
+        # point as well
+        if annotation.endswith("_RW"):
+            annotation = annotation[:-1]
+
         if dtype == str and dims == (1,):
-            self.value = ''
+            self.values[annotation] = ''
         elif dims == (1,):
-            self.value = dtype(0)
+            self.values[annotation] = dtype(0)
         else:
-            self.value = numpy.zeros(dims, dtype)
+            self.values[annotation] = numpy.zeros(dims, dtype)
+
 
         def read_function():
-            logger.debug("from read_function, reading {} array of type {}".format(dims, dtype))
-            return self.value
+            logger.debug("from read_function, reading {}: {} array of type {} == {}".format(annotation, dims, dtype, self.values[annotation]))
+            return self.values[annotation]
 
         def write_function(write_value):
-            logger.debug("from write_function, writing {} array of type {}".format(dims, dtype))
+            logger.debug("from write_function, writing {}: {} array of type {}".format(annotation, dims, dtype))
 
-            self.value = write_value
-            return
+            self.values[annotation] = write_value
 
         logger.debug("created and bound example_client read/write functions to attribute_wrapper object")
         return read_function, write_function
@@ -106,7 +115,7 @@ class test_client(CommClient):
         dims, dtype = self._setup_value_conversion(attribute)
 
         # configure and return the read/write functions
-        read_function, write_function = self._setup_mapping(dims, dtype)
+        read_function, write_function = self._setup_mapping(annotation, dims, dtype)
 
         # return the read/write functions
         return read_function, write_function