diff --git a/tests/test_timeseries.py b/tests/test_timeseries.py
index 10745b79981e4d61ff5de1773e943d1a38acd44c..63acb5fac5052f562af165bce0ce6a36fa4f39a2 100644
--- a/tests/test_timeseries.py
+++ b/tests/test_timeseries.py
@@ -1076,6 +1076,63 @@ class TestApps:
         assert response_json['changelog'][0]['type_of_change'] == 'comprehensive metadata revision'
 
 
+    def test_patch_timeseries_roles(self, client, db):
+        response = client.patch("/timeseries/id/1?description=changed roles",
+                json={"timeseries": 
+                          {"roles": [{"role": "ResourceProvider", "contact_id": 5, "status": "Active"}]
+                          }
+                     }
+        )
+        expected_status_code = 200
+        assert response.status_code == expected_status_code
+        expected_resp = {'detail': { 'message': 'timeseries patched.',
+                                     'timeseries_id': 1 }
+                        } 
+        response_json = response.json()
+        assert response_json == expected_resp
+        response = client.get(f"/timeseries/id/{response_json['detail']['timeseries_id']}")
+        response_json = response.json()
+        # just check special changes
+        response_roles = [{'contact': {'id': 5,
+                                       'organisation': {'city': 'Jülich',
+                                                        'contact_url': 'mailto:toar-data@fz-juelich.de',
+                                                        'country': 'Germany',
+                                                        'homepage': 'https://www.fz-juelich.de',
+                                                        'id': 2,
+                                                        'kind': 'research',
+                                                        'longname': 'Forschungszentrum Jülich',
+                                                        'name': 'FZJ',
+                                                        'postcode': '52425',
+                                                        'street_address': 'Wilhelm-Johnen-Straße',
+                                                    },
+                                                },
+                           'id': 1,
+                           'role': 'resource provider',
+                           'status': 'active'},
+                          {'contact': {'id': 4,
+                                       'organisation': {'city': 'Dessau-Roßlau',
+                                                        'contact_url': 'mailto:immission@uba.de',
+                                                        'country': 'Germany',
+                                                        'homepage': 'https://www.umweltbundesamt.de',
+                                                        'id': 1,
+                                                        'kind': 'government',
+                                                        'longname': 'Umweltbundesamt',
+                                                        'name': 'UBA',
+                                                        'postcode': '06844',
+                                                        'street_address': 'Wörlitzer Platz 1',
+                                                        'contact_url': 'mailto:immission@uba.de'}},
+                           'id': 2,
+                           'role': 'resource provider',
+                           'status': 'active'}]
+        set_expected_response_roles = {json.dumps(item, sort_keys=True) for item in response_roles}
+        set_response_roles = {json.dumps(item, sort_keys=True) for item in response_json['roles']}
+        assert set_response_roles == set_expected_response_roles
+        assert response_json['changelog'][0]['old_value'] == "{'roles': [{'role': 'ResourceProvider', 'status': 'Active', 'contact_id': 4}]}"
+        assert response_json['changelog'][0]['new_value'] == "{'roles': [{'role': 'ResourceProvider', 'status': 'Active', 'contact_id': 4}, {'role': 'ResourceProvider', 'contact_id': 5, 'status': 'Active'}]}"
+        assert response_json['changelog'][0]['author_id'] == 1
+        assert response_json['changelog'][0]['type_of_change'] == 'single value correction in metadata'
+
+
     """def test_get_timeseries_changelog(self, client, db):
         response = client.get("/timeseries_changelog/{id}")
         expected_status_code = 200
diff --git a/toardb/timeseries/crud.py b/toardb/timeseries/crud.py
index bc3a7ea31a8b67749db109de7c05a2debf4e4906..e700ef32138111350a9d31359f9448dcc4805fd4 100644
--- a/toardb/timeseries/crud.py
+++ b/toardb/timeseries/crud.py
@@ -799,6 +799,7 @@ def patch_timeseries(db: Session, description: str, timeseries_id: int, timeseri
     no_log = (description == 'NOLOG')
     if not no_log:
         old_values={}
+        new_values={}
         for k, v in timeseries_dict2.items():
             field=str(getattr(db_timeseries,k))
             if k == 'additional_metadata':
@@ -848,8 +849,11 @@ def patch_timeseries(db: Session, description: str, timeseries_id: int, timeseri
                 old_value['contact_id'] =  old_role.contact_id
                 old_roles.append(old_value)
             old_values['roles'] = old_roles
+            new_roles = old_roles.copy()
         for r in roles_data:
             db_role = models.TimeseriesRole(**r)
+            if not no_log:
+                new_roles.append(r)
             db_role.role = get_value_from_str(toardb.toardb.RC_vocabulary,db_role.role)
             db_role.status = get_value_from_str(toardb.toardb.RS_vocabulary,db_role.status)
             # check whether role is already present in database
@@ -863,6 +867,8 @@ def patch_timeseries(db: Session, description: str, timeseries_id: int, timeseri
                 role_id = db_role.id
             db.execute(insert(timeseries_timeseries_roles_table).values(timeseries_id=timeseries_id, role_id=role_id))
             db.commit()
+        if not no_log:
+            new_values['roles'] = new_roles
     # store annotations and update association table
     if annotations_data:
         if not no_log:
@@ -895,6 +901,8 @@ def patch_timeseries(db: Session, description: str, timeseries_id: int, timeseri
             db.commit()
     # add patch to changelog table
     if not no_log:
+        if new_values:
+            timeseries_dict2.update(new_values)
         db_changelog = TimeseriesChangelog(description=description, timeseries_id=timeseries_id, author_id=author_id, type_of_change=type_of_change,
                                            old_value=str(old_values), new_value=str(timeseries_dict2))
         db.add(db_changelog)