119119from zarr .core .sync import sync
120120from zarr .errors import (
121121 ArrayNotFoundError ,
122+ ContainsArrayError ,
122123 MetadataValidationError ,
123124 ZarrDeprecationWarning ,
124125 ZarrUserWarning ,
@@ -1496,14 +1497,23 @@ async def _save_metadata(self, metadata: ArrayMetadata, ensure_parents: bool = F
14961497 Asynchronously save the array metadata.
14971498 """
14981499 to_save = metadata .to_buffer_dict (cpu_buffer_prototype )
1499- awaitables = [set_or_delete (self .store_path / key , value ) for key , value in to_save .items ()]
1500+ set_awaitables = [
1501+ set_or_delete (self .store_path / key , value ) for key , value in to_save .items ()
1502+ ]
15001503
15011504 if ensure_parents :
15021505 # To enable zarr.create(store, path="a/b/c"), we need to create all the intermediate groups.
15031506 parents = _build_parents (self )
1507+ ensure_array_awaitables = []
15041508
15051509 for parent in parents :
1506- awaitables .extend (
1510+ # Error if an array already exists at any parent location. Only groups can have child nodes.
1511+ ensure_array_awaitables .append (
1512+ ensure_no_existing_node (
1513+ parent .store_path , metadata .zarr_format , node_type = "array"
1514+ )
1515+ )
1516+ set_awaitables .extend (
15071517 [
15081518 (parent .store_path / key ).set_if_not_exists (value )
15091519 for key , value in parent .metadata .to_buffer_dict (
@@ -1512,7 +1522,16 @@ async def _save_metadata(self, metadata: ArrayMetadata, ensure_parents: bool = F
15121522 ]
15131523 )
15141524
1515- await gather (* awaitables )
1525+ # Checks for parent arrays must happen first, before any metadata is modified
1526+ try :
1527+ await gather (* ensure_array_awaitables )
1528+ except ContainsArrayError as e :
1529+ set_awaitables = [] # clear awaitables to avoid printed RuntimeWarning: coroutine was never awaited
1530+ raise ValueError (
1531+ f"A parent of { self .store_path } is an array - only groups may have child nodes."
1532+ ) from e
1533+
1534+ await gather (* set_awaitables )
15161535
15171536 async def _set_selection (
15181537 self ,
0 commit comments