We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Annotation CIV disapears after uploading image CIV
**Describe the bug**
When uploading a Generic Overlay CIV to an archive item that contains one or multiple annotations CIVs (tested with 2D bounding box and point annotations), those annotations disappear.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to an archive item that contains some annotation CIVs
2. Upload an image CIV to the archive item.
3. Refresh to see the annotation CIVs disappeared from the archive item.


**Expected behavior**
The annotation CIVs should remain.

**Screenshots**

https://github.com/comic/grand-challenge.org/assets/2001094/7e54b5c1-4d17-40ae-8ebc-9acf743861cd



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `app/grandchallenge/archives/tasks.py`
Content:
```
1 from celery import chain, group, shared_task
2 from django.conf import settings
3 from django.db import transaction
4 from django.db.transaction import on_commit
5 
6 from grandchallenge.archives.models import Archive, ArchiveItem
7 from grandchallenge.cases.models import Image, RawImageUploadSession
8 from grandchallenge.cases.tasks import build_images
9 from grandchallenge.components.models import (
10     ComponentInterface,
11     ComponentInterfaceValue,
12 )
13 from grandchallenge.components.tasks import (
14     add_image_to_component_interface_value,
15 )
16 
17 
18 @shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS["acks-late-micro-short"])
19 def add_images_to_archive(*, upload_session_pk, archive_pk, interface_pk=None):
20     with transaction.atomic():
21         images = Image.objects.filter(origin_id=upload_session_pk)
22         archive = Archive.objects.get(pk=archive_pk)
23         if interface_pk is not None:
24             interface = ComponentInterface.objects.get(pk=interface_pk)
25         else:
26             interface = ComponentInterface.objects.get(
27                 slug="generic-medical-image"
28             )
29 
30         for image in images:
31             civ = ComponentInterfaceValue.objects.filter(
32                 interface=interface, image=image
33             ).first()
34             if civ is None:
35                 civ = ComponentInterfaceValue.objects.create(
36                     interface=interface, image=image
37                 )
38             if ArchiveItem.objects.filter(
39                 archive=archive, values__in=[civ.pk]
40             ).exists():
41                 continue
42             item = ArchiveItem.objects.create(archive=archive)
43             item.values.set([civ])
44 
45 
46 @shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS["acks-late-micro-short"])
47 def add_images_to_archive_item(
48     *, upload_session_pk, archive_item_pk, interface_pk
49 ):
50     archive_item = ArchiveItem.objects.get(pk=archive_item_pk)
51     interface = ComponentInterface.objects.get(pk=interface_pk)
52     session = RawImageUploadSession.objects.get(pk=upload_session_pk)
53 
54     if archive_item.values.filter(
55         interface=interface, image__in=session.image_set.all()
56     ).exists():
57         return
58 
59     with transaction.atomic():
60         archive_item.values.remove(
61             *archive_item.values.filter(interface=interface)
62         )
63         new_civ = ComponentInterfaceValue.objects.create(interface=interface)
64         archive_item.values.add(new_civ)
65 
66         on_commit(
67             add_image_to_component_interface_value.signature(
68                 kwargs={
69                     "component_interface_value_pk": new_civ.pk,
70                     "upload_session_pk": upload_session_pk,
71                 },
72                 immutable=True,
73             ).apply_async
74         )
75 
76 
77 def update_archive_item_update_kwargs(
78     instance,
79     interface,
80     civ_pks_to_add,
81     upload_pks,
82     value=None,
83     image=None,
84     user_upload=None,
85     upload_session=None,
86 ):
87     """
88     Given an interface and a value/image/user_upload/upload_session, this task
89     determines whether to create a new CIV for the specified archive item instance
90     with those values, and whether to delete any existing CIVs from the archive item.
91     It appends the respective CIV pk(s) to the set of to be added and removed
92     civs and returns those. If an upload_session is specified,
93     it also appends the session pk together with the new civ pk to the list of
94     to be processed images.
95     """
96     with transaction.atomic():
97         if interface.is_image_kind:
98             if image:
99                 civ, created = ComponentInterfaceValue.objects.get_or_create(
100                     interface=interface, image=image
101                 )
102                 if created:
103                     civ.full_clean()
104                     civ.save()
105             elif upload_session:
106                 civ = ComponentInterfaceValue.objects.create(
107                     interface=interface
108                 )
109                 upload_pks[civ.pk] = upload_session.pk
110                 civ.save()
111             civ_pks_to_add.add(civ.pk)
112         elif interface.requires_file:
113             civ = ComponentInterfaceValue.objects.create(interface=interface)
114             user_upload.copy_object(to_field=civ.file)
115             civ.full_clean()
116             civ.save()
117             user_upload.delete()
118             civ_pks_to_add.add(civ.pk)
119         else:
120             civ = interface.create_instance(value=value)
121             civ_pks_to_add.add(civ.pk)
122 
123 
124 @shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS["acks-late-micro-short"])
125 def update_archive_item_values(*, archive_item_pk, civ_pks_to_add):
126     instance = ArchiveItem.objects.get(pk=archive_item_pk)
127     civ_pks_to_remove = []
128     civs = ComponentInterfaceValue.objects.filter(pk__in=civ_pks_to_add)
129     for civ in civs:
130         if instance.values.filter(interface=civ.interface.pk).exists():
131             for civ_pk in instance.values.filter(
132                 interface=civ.interface.pk
133             ).values_list("pk", flat=True):
134                 civ_pks_to_remove.append(civ_pk)
135         # for images, check if there are any CIVs with the provided image
136         if civ.interface.is_image_kind:
137             if instance.values.filter(image=civ.image).exists():
138                 for civ_pk in instance.values.filter(
139                     image=civ.image
140                 ).values_list("pk", flat=True):
141                     civ_pks_to_remove.append(civ_pk)
142 
143     with transaction.atomic():
144         instance.values.remove(*civ_pks_to_remove)
145         instance.values.add(*civ_pks_to_add)
146 
147 
148 @shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS["acks-late-micro-short"])
149 def start_archive_item_update_tasks(
150     archive_item_pk, civ_pks_to_add, upload_pks
151 ):
152     tasks = update_archive_item_values.signature(
153         kwargs={
154             "archive_item_pk": archive_item_pk,
155             "civ_pks_to_add": civ_pks_to_add,
156         },
157         immutable=True,
158     )
159 
160     if len(upload_pks) > 0:
161         image_tasks = group(
162             # Chords and iterator groups are broken in Celery, send a list
163             # instead, see https://github.com/celery/celery/issues/7285
164             [
165                 chain(
166                     build_images.signature(
167                         kwargs={"upload_session_pk": upload_pk}
168                     ),
169                     add_image_to_component_interface_value.signature(
170                         kwargs={
171                             "component_interface_value_pk": civ_pk,
172                             "upload_session_pk": upload_pk,
173                         },
174                         immutable=True,
175                     ),
176                 )
177                 for civ_pk, upload_pk in upload_pks.items()
178             ]
179         )
180         tasks = group(image_tasks, tasks)
181 
182     with transaction.atomic():
183         on_commit(tasks.apply_async)
184
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/app/grandchallenge/archives/tasks.py b/app/grandchallenge/archives/tasks.py
--- a/app/grandchallenge/archives/tasks.py
+++ b/app/grandchallenge/archives/tasks.py
@@ -133,7 +133,9 @@
             ).values_list("pk", flat=True):
                 civ_pks_to_remove.append(civ_pk)
         # for images, check if there are any CIVs with the provided image
-        if civ.interface.is_image_kind:
+        # this is necessary to enable updating the interface
+        # of a given image via the API
+        if civ.interface.is_image_kind and civ.image:
             if instance.values.filter(image=civ.image).exists():
                 for civ_pk in instance.values.filter(
                     image=civ.image

{"golden_diff": "diff --git a/app/grandchallenge/archives/tasks.py b/app/grandchallenge/archives/tasks.py\n--- a/app/grandchallenge/archives/tasks.py\n+++ b/app/grandchallenge/archives/tasks.py\n@@ -133,7 +133,9 @@\n             ).values_list(\"pk\", flat=True):\n                 civ_pks_to_remove.append(civ_pk)\n         # for images, check if there are any CIVs with the provided image\n-        if civ.interface.is_image_kind:\n+        # this is necessary to enable updating the interface\n+        # of a given image via the API\n+        if civ.interface.is_image_kind and civ.image:\n             if instance.values.filter(image=civ.image).exists():\n                 for civ_pk in instance.values.filter(\n                     image=civ.image\n", "issue": "Annotation CIV disapears after uploading image CIV\n**Describe the bug**\r\nWhen uploading a Generic Overlay CIV to an archive item that contains one or multiple annotations CIVs (tested with 2D bounding box and point annotations), those annotations disappear.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Go to an archive item that contains some annotation CIVs\r\n2. Upload an image CIV to the archive item.\r\n3. Refresh to see the annotation CIVs disappeared from the archive item.\r\n\r\n\r\n**Expected behavior**\r\nThe annotation CIVs should remain.\r\n\r\n**Screenshots**\r\n\r\nhttps://github.com/comic/grand-challenge.org/assets/2001094/7e54b5c1-4d17-40ae-8ebc-9acf743861cd\r\n\r\n\n", "before_files": [{"content": "from celery import chain, group, shared_task\nfrom django.conf import settings\nfrom django.db import transaction\nfrom django.db.transaction import on_commit\n\nfrom grandchallenge.archives.models import Archive, ArchiveItem\nfrom grandchallenge.cases.models import Image, RawImageUploadSession\nfrom grandchallenge.cases.tasks import build_images\nfrom grandchallenge.components.models import (\n    ComponentInterface,\n    ComponentInterfaceValue,\n)\nfrom grandchallenge.components.tasks import (\n    add_image_to_component_interface_value,\n)\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef add_images_to_archive(*, upload_session_pk, archive_pk, interface_pk=None):\n    with transaction.atomic():\n        images = Image.objects.filter(origin_id=upload_session_pk)\n        archive = Archive.objects.get(pk=archive_pk)\n        if interface_pk is not None:\n            interface = ComponentInterface.objects.get(pk=interface_pk)\n        else:\n            interface = ComponentInterface.objects.get(\n                slug=\"generic-medical-image\"\n            )\n\n        for image in images:\n            civ = ComponentInterfaceValue.objects.filter(\n                interface=interface, image=image\n            ).first()\n            if civ is None:\n                civ = ComponentInterfaceValue.objects.create(\n                    interface=interface, image=image\n                )\n            if ArchiveItem.objects.filter(\n                archive=archive, values__in=[civ.pk]\n            ).exists():\n                continue\n            item = ArchiveItem.objects.create(archive=archive)\n            item.values.set([civ])\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef add_images_to_archive_item(\n    *, upload_session_pk, archive_item_pk, interface_pk\n):\n    archive_item = ArchiveItem.objects.get(pk=archive_item_pk)\n    interface = ComponentInterface.objects.get(pk=interface_pk)\n    session = RawImageUploadSession.objects.get(pk=upload_session_pk)\n\n    if archive_item.values.filter(\n        interface=interface, image__in=session.image_set.all()\n    ).exists():\n        return\n\n    with transaction.atomic():\n        archive_item.values.remove(\n            *archive_item.values.filter(interface=interface)\n        )\n        new_civ = ComponentInterfaceValue.objects.create(interface=interface)\n        archive_item.values.add(new_civ)\n\n        on_commit(\n            add_image_to_component_interface_value.signature(\n                kwargs={\n                    \"component_interface_value_pk\": new_civ.pk,\n                    \"upload_session_pk\": upload_session_pk,\n                },\n                immutable=True,\n            ).apply_async\n        )\n\n\ndef update_archive_item_update_kwargs(\n    instance,\n    interface,\n    civ_pks_to_add,\n    upload_pks,\n    value=None,\n    image=None,\n    user_upload=None,\n    upload_session=None,\n):\n    \"\"\"\n    Given an interface and a value/image/user_upload/upload_session, this task\n    determines whether to create a new CIV for the specified archive item instance\n    with those values, and whether to delete any existing CIVs from the archive item.\n    It appends the respective CIV pk(s) to the set of to be added and removed\n    civs and returns those. If an upload_session is specified,\n    it also appends the session pk together with the new civ pk to the list of\n    to be processed images.\n    \"\"\"\n    with transaction.atomic():\n        if interface.is_image_kind:\n            if image:\n                civ, created = ComponentInterfaceValue.objects.get_or_create(\n                    interface=interface, image=image\n                )\n                if created:\n                    civ.full_clean()\n                    civ.save()\n            elif upload_session:\n                civ = ComponentInterfaceValue.objects.create(\n                    interface=interface\n                )\n                upload_pks[civ.pk] = upload_session.pk\n                civ.save()\n            civ_pks_to_add.add(civ.pk)\n        elif interface.requires_file:\n            civ = ComponentInterfaceValue.objects.create(interface=interface)\n            user_upload.copy_object(to_field=civ.file)\n            civ.full_clean()\n            civ.save()\n            user_upload.delete()\n            civ_pks_to_add.add(civ.pk)\n        else:\n            civ = interface.create_instance(value=value)\n            civ_pks_to_add.add(civ.pk)\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef update_archive_item_values(*, archive_item_pk, civ_pks_to_add):\n    instance = ArchiveItem.objects.get(pk=archive_item_pk)\n    civ_pks_to_remove = []\n    civs = ComponentInterfaceValue.objects.filter(pk__in=civ_pks_to_add)\n    for civ in civs:\n        if instance.values.filter(interface=civ.interface.pk).exists():\n            for civ_pk in instance.values.filter(\n                interface=civ.interface.pk\n            ).values_list(\"pk\", flat=True):\n                civ_pks_to_remove.append(civ_pk)\n        # for images, check if there are any CIVs with the provided image\n        if civ.interface.is_image_kind:\n            if instance.values.filter(image=civ.image).exists():\n                for civ_pk in instance.values.filter(\n                    image=civ.image\n                ).values_list(\"pk\", flat=True):\n                    civ_pks_to_remove.append(civ_pk)\n\n    with transaction.atomic():\n        instance.values.remove(*civ_pks_to_remove)\n        instance.values.add(*civ_pks_to_add)\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef start_archive_item_update_tasks(\n    archive_item_pk, civ_pks_to_add, upload_pks\n):\n    tasks = update_archive_item_values.signature(\n        kwargs={\n            \"archive_item_pk\": archive_item_pk,\n            \"civ_pks_to_add\": civ_pks_to_add,\n        },\n        immutable=True,\n    )\n\n    if len(upload_pks) > 0:\n        image_tasks = group(\n            # Chords and iterator groups are broken in Celery, send a list\n            # instead, see https://github.com/celery/celery/issues/7285\n            [\n                chain(\n                    build_images.signature(\n                        kwargs={\"upload_session_pk\": upload_pk}\n                    ),\n                    add_image_to_component_interface_value.signature(\n                        kwargs={\n                            \"component_interface_value_pk\": civ_pk,\n                            \"upload_session_pk\": upload_pk,\n                        },\n                        immutable=True,\n                    ),\n                )\n                for civ_pk, upload_pk in upload_pks.items()\n            ]\n        )\n        tasks = group(image_tasks, tasks)\n\n    with transaction.atomic():\n        on_commit(tasks.apply_async)\n", "path": "app/grandchallenge/archives/tasks.py"}], "after_files": [{"content": "from celery import chain, group, shared_task\nfrom django.conf import settings\nfrom django.db import transaction\nfrom django.db.transaction import on_commit\n\nfrom grandchallenge.archives.models import Archive, ArchiveItem\nfrom grandchallenge.cases.models import Image, RawImageUploadSession\nfrom grandchallenge.cases.tasks import build_images\nfrom grandchallenge.components.models import (\n    ComponentInterface,\n    ComponentInterfaceValue,\n)\nfrom grandchallenge.components.tasks import (\n    add_image_to_component_interface_value,\n)\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef add_images_to_archive(*, upload_session_pk, archive_pk, interface_pk=None):\n    with transaction.atomic():\n        images = Image.objects.filter(origin_id=upload_session_pk)\n        archive = Archive.objects.get(pk=archive_pk)\n        if interface_pk is not None:\n            interface = ComponentInterface.objects.get(pk=interface_pk)\n        else:\n            interface = ComponentInterface.objects.get(\n                slug=\"generic-medical-image\"\n            )\n\n        for image in images:\n            civ = ComponentInterfaceValue.objects.filter(\n                interface=interface, image=image\n            ).first()\n            if civ is None:\n                civ = ComponentInterfaceValue.objects.create(\n                    interface=interface, image=image\n                )\n            if ArchiveItem.objects.filter(\n                archive=archive, values__in=[civ.pk]\n            ).exists():\n                continue\n            item = ArchiveItem.objects.create(archive=archive)\n            item.values.set([civ])\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef add_images_to_archive_item(\n    *, upload_session_pk, archive_item_pk, interface_pk\n):\n    archive_item = ArchiveItem.objects.get(pk=archive_item_pk)\n    interface = ComponentInterface.objects.get(pk=interface_pk)\n    session = RawImageUploadSession.objects.get(pk=upload_session_pk)\n\n    if archive_item.values.filter(\n        interface=interface, image__in=session.image_set.all()\n    ).exists():\n        return\n\n    with transaction.atomic():\n        archive_item.values.remove(\n            *archive_item.values.filter(interface=interface)\n        )\n        new_civ = ComponentInterfaceValue.objects.create(interface=interface)\n        archive_item.values.add(new_civ)\n\n        on_commit(\n            add_image_to_component_interface_value.signature(\n                kwargs={\n                    \"component_interface_value_pk\": new_civ.pk,\n                    \"upload_session_pk\": upload_session_pk,\n                },\n                immutable=True,\n            ).apply_async\n        )\n\n\ndef update_archive_item_update_kwargs(\n    instance,\n    interface,\n    civ_pks_to_add,\n    upload_pks,\n    value=None,\n    image=None,\n    user_upload=None,\n    upload_session=None,\n):\n    \"\"\"\n    Given an interface and a value/image/user_upload/upload_session, this task\n    determines whether to create a new CIV for the specified archive item instance\n    with those values, and whether to delete any existing CIVs from the archive item.\n    It appends the respective CIV pk(s) to the set of to be added and removed\n    civs and returns those. If an upload_session is specified,\n    it also appends the session pk together with the new civ pk to the list of\n    to be processed images.\n    \"\"\"\n    with transaction.atomic():\n        if interface.is_image_kind:\n            if image:\n                civ, created = ComponentInterfaceValue.objects.get_or_create(\n                    interface=interface, image=image\n                )\n                if created:\n                    civ.full_clean()\n                    civ.save()\n            elif upload_session:\n                civ = ComponentInterfaceValue.objects.create(\n                    interface=interface\n                )\n                upload_pks[civ.pk] = upload_session.pk\n                civ.save()\n            civ_pks_to_add.add(civ.pk)\n        elif interface.requires_file:\n            civ = ComponentInterfaceValue.objects.create(interface=interface)\n            user_upload.copy_object(to_field=civ.file)\n            civ.full_clean()\n            civ.save()\n            user_upload.delete()\n            civ_pks_to_add.add(civ.pk)\n        else:\n            civ = interface.create_instance(value=value)\n            civ_pks_to_add.add(civ.pk)\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef update_archive_item_values(*, archive_item_pk, civ_pks_to_add):\n    instance = ArchiveItem.objects.get(pk=archive_item_pk)\n    civ_pks_to_remove = []\n    civs = ComponentInterfaceValue.objects.filter(pk__in=civ_pks_to_add)\n    for civ in civs:\n        if instance.values.filter(interface=civ.interface.pk).exists():\n            for civ_pk in instance.values.filter(\n                interface=civ.interface.pk\n            ).values_list(\"pk\", flat=True):\n                civ_pks_to_remove.append(civ_pk)\n        # for images, check if there are any CIVs with the provided image\n        # this is necessary to enable updating the interface\n        # of a given image via the API\n        if civ.interface.is_image_kind and civ.image:\n            if instance.values.filter(image=civ.image).exists():\n                for civ_pk in instance.values.filter(\n                    image=civ.image\n                ).values_list(\"pk\", flat=True):\n                    civ_pks_to_remove.append(civ_pk)\n\n    with transaction.atomic():\n        instance.values.remove(*civ_pks_to_remove)\n        instance.values.add(*civ_pks_to_add)\n\n\n@shared_task(**settings.CELERY_TASK_DECORATOR_KWARGS[\"acks-late-micro-short\"])\ndef start_archive_item_update_tasks(\n    archive_item_pk, civ_pks_to_add, upload_pks\n):\n    tasks = update_archive_item_values.signature(\n        kwargs={\n            \"archive_item_pk\": archive_item_pk,\n            \"civ_pks_to_add\": civ_pks_to_add,\n        },\n        immutable=True,\n    )\n\n    if len(upload_pks) > 0:\n        image_tasks = group(\n            # Chords and iterator groups are broken in Celery, send a list\n            # instead, see https://github.com/celery/celery/issues/7285\n            [\n                chain(\n                    build_images.signature(\n                        kwargs={\"upload_session_pk\": upload_pk}\n                    ),\n                    add_image_to_component_interface_value.signature(\n                        kwargs={\n                            \"component_interface_value_pk\": civ_pk,\n                            \"upload_session_pk\": upload_pk,\n                        },\n                        immutable=True,\n                    ),\n                )\n                for civ_pk, upload_pk in upload_pks.items()\n            ]\n        )\n        tasks = group(image_tasks, tasks)\n\n    with transaction.atomic():\n        on_commit(tasks.apply_async)\n", "path": "app/grandchallenge/archives/tasks.py"}]}