diff --git a/rocrate/rocrate.py b/rocrate/rocrate.py
index 57bcd39..5d5a98d 100644
--- a/rocrate/rocrate.py
+++ b/rocrate/rocrate.py
@@ -142,7 +142,7 @@ class ROCrate():
 
         root_entity = entities.pop(root_id)
         assert root_id == root_entity.pop('@id')
-        parts = root_entity.pop('hasPart', [])
+        parts = as_list(root_entity.pop('hasPart', []))
         self.add(RootDataset(self, root_id, properties=root_entity))
         preview_entity = entities.pop(Preview.BASENAME, None)
         if preview_entity and not gen_preview:
@@ -167,7 +167,7 @@ class ROCrate():
                 else:
                     instance = cls(self, source / id_, id_, properties=entity)
             self.add(instance)
-            self.__add_parts(entity.get("hasPart", []), entities, source)
+            self.__add_parts(as_list(entity.get("hasPart", [])), entities, source)
 
     def __read_contextual_entities(self, entities):
         type_map = {_.__name__: _ for _ in subclasses(ContextEntity)}

diff --git a/test/test_read.py b/test/test_read.py
index 9aa3e96..43bf328 100644
--- a/test/test_read.py
+++ b/test/test_read.py
@@ -499,17 +499,17 @@ def test_indirect_data_entity(tmpdir):
             {
                 "@id": "./",
                 "@type": "Dataset",
-                "hasPart": [{"@id": "d1"}]
+                "hasPart": {"@id": "d1"}
             },
             {
                 "@id": "d1",
                 "@type": "Dataset",
-                "hasPart": [{"@id": "d1/d2"}]
+                "hasPart": {"@id": "d1/d2"}
             },
             {
                 "@id": "d1/d2",
                 "@type": "Dataset",
-                "hasPart": [{"@id": "d1/d2/f1"}]
+                "hasPart": {"@id": "d1/d2/f1"}
             },
             {
                 "@id": "d1/d2/f1",

hasPart property on root dataset is assumed to be an array
Loading this dataset causes an error as the hasPart value is not an array but the code assumes it will be :

```json
{
    "@id": "./",
    "@type": "Dataset",
    "hasPart":  {"@id": "spam/foo.txt"} 
},
{
    "@id": "spam/foo.txt",
    "@type": "File"
}
```

This line is the culprit: https://github.com/ResearchObject/ro-crate-py/blob/dc3f75b0d0390dedbf9a830b6325b76dba468f1f/rocrate/rocrate.py#L145C1-L146C1

 parts = root_entity.pop('hasPart', [])

I added this to my copy  make it work but not sure if you have a general purpose way of doing this in this library:

        if not isinstance(parts, list):
            parts = [parts]


test/test_read.py::test_indirect_data_entity
test/test_read.py::test_crate_dir_loading[False-False] test/test_read.py::test_crate_dir_loading[True-False] test/test_read.py::test_crate_dir_loading[True-True] test/test_read.py::test_legacy_crate test/test_read.py::test_bad_crate test/test_read.py::test_init[False] test/test_read.py::test_init[True] test/test_read.py::test_exclude test/test_read.py::test_init_preview[False-False] test/test_read.py::test_init_preview[False-True] test/test_read.py::test_init_preview[True-False] test/test_read.py::test_init_preview[True-True] test/test_read.py::test_no_parts test/test_read.py::test_extra_data[False] test/test_read.py::test_extra_data[True] test/test_read.py::test_missing_dir test/test_read.py::test_missing_file test/test_read.py::test_generic_data_entity test/test_read.py::test_root_conformsto test/test_read.py::test_multi_type_context_entity