diff --git a/SAS/TMSS/backend/src/CMakeLists.txt b/SAS/TMSS/backend/src/CMakeLists.txt
index f80c85dc26bfdd8d5a769f107b6b4e0830c00016..167c3911f70d60354827352a249b0b3c8fc75394 100644
--- a/SAS/TMSS/backend/src/CMakeLists.txt
+++ b/SAS/TMSS/backend/src/CMakeLists.txt
@@ -32,7 +32,6 @@ find_python_module(swagger_spec_validator REQUIRED) # pip3 install swagger-spec-
 
 set(_py_files
     manage.py
-    remakemigrations.py
     )
 
 python_install(${_py_files}
diff --git a/SAS/TMSS/backend/src/remakemigrations.py b/SAS/TMSS/backend/src/remakemigrations.py
deleted file mode 100755
index ceb04af2b7220d8f40cc0ebb7c75d17b8edd48dd..0000000000000000000000000000000000000000
--- a/SAS/TMSS/backend/src/remakemigrations.py
+++ /dev/null
@@ -1,283 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018    ASTRON (Netherlands Institute for Radio Astronomy)
-# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
-#
-# This file is part of the LOFAR software suite.
-# The LOFAR software suite is free software: you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# The LOFAR software suite is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
-
-# $Id:  $
-
-# This script automates the procedure to replace the existing migrations on the source tree with initital migrations
-# based on the current datamodel. Django offers a call 'makemigrations' through manage.py, which creates new migrations
-# after the datamodel implementation has changed. These additional migrations apply those changes to an existing
-# database reflecting the previous datamodel.
-# This is a very nice feature for production, but there are a few downsides that this script tackles:
-#
-# 1. During development, where the datamodel constantly changes, whe typically don't want a ton of iterative migrations,
-# but just have a clean start with a fresh initial database state without the whole provenance is perfectly fine. (We
-# start up a fresh database anyway for every test or test deployment.) This can be achieved by removing all existing
-# migrations prior to creating new ones.
-# A difficulty with this approach is that we do have a manual migration to populate the database with fixtures.
-# This migration needs to be restored or re-created after Django created fresh migrations for the database itself.
-#
-# 2. Since in settings.py we refer to the tmss app in the lofar environment, Django uses the build or installed version.
-# A consequence is that the created migrations are placed in there and need to be copied to the source tree.
-#
-# This script requires a running postgres database instance to work against.
-# To use specific database credentials, run e.g. ./remakemigrations.py -C b5f881c4-d41a-4f24-b9f5-23cd6a7f37d0
-
-
-import os
-from glob import glob
-import subprocess as sp
-import logging
-import argparse
-from shutil import copy
-import lofar.sas.tmss
-
-logger = logging.getLogger(__file__)
-
-# set up paths
-tmss_source_directory = os.path.dirname(__file__)
-if tmss_source_directory == '':
-    tmss_source_directory = '.'
-tmss_env_directory = os.path.dirname(lofar.sas.tmss.__file__)
-relative_migrations_directory = '/tmss/tmssapp/migrations/'
-
-# template for manual changes and fixture (applied last):
-template = """
-#
-# auto-generated by remakemigrations.py
-#
-# ! Please make sure to apply any changes to the template in that script !
-#
-from django.db import migrations
-
-from lofar.sas.tmss.tmss.tmssapp.populate import *
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('tmssapp', '{migration_dependency}'),
-    ]
-
-    operations = [ migrations.RunSQL('ALTER SEQUENCE tmssapp_SubTask_id_seq RESTART WITH 2000000;'), # Start SubTask id with 2 000 000 to avoid overlap with 'old' (test/production) OTDB
-                   # add an SQL trigger in the database enforcing correct state transitions.
-                   # it is crucial that illegal subtask state transitions are block at the "lowest level" (i.e.: in the database) so we can guarantee that the subtask state machine never breaks.
-                   # see: https://support.astron.nl/confluence/display/TMSS/Subtask+State+Machine
-                   # Explanation of SQl below: A trigger function is called upon each create/update of the subtask.
-                   # If the state changes, then it is checked if the state transition from old to new is present in the SubtaskAllowedStateTransitions table.
-                   # If not an Exception is raised, thus enforcing a rollback, thus enforcing the state machine to follow the design.
-                   # It is thereby enforced upon the user/caller to handle these blocked illegal state transitions, and act more wisely.
-                   migrations.RunSQL('''CREATE OR REPLACE FUNCTION tmssapp_check_subtask_state_transition()
-                                     RETURNS trigger AS
-                                     $BODY$
-                                     BEGIN
-                                       IF TG_OP = 'INSERT' THEN
-                                         IF NOT (SELECT EXISTS(SELECT id FROM tmssapp_subtaskallowedstatetransitions WHERE old_state_id IS NULL AND new_state_id=NEW.state_id)) THEN
-                                            RAISE EXCEPTION 'ILLEGAL SUBTASK STATE TRANSITION FROM % TO %', NULL, NEW.state_id;
-                                         END IF;
-                                       END IF;
-                                       IF TG_OP = 'UPDATE' THEN
-                                         IF OLD.state_id <> NEW.state_id AND NOT (SELECT EXISTS(SELECT id FROM tmssapp_subtaskallowedstatetransitions WHERE old_state_id=OLD.state_id AND new_state_id=NEW.state_id)) THEN
-                                           RAISE EXCEPTION 'ILLEGAL SUBTASK STATE TRANSITION FROM "%" TO "%"', OLD.state_id, NEW.state_id;
-                                         END IF;
-                                       END IF;
-                                     RETURN NEW;
-                                     END;
-                                     $BODY$
-                                     LANGUAGE plpgsql VOLATILE;
-                                     DROP TRIGGER IF EXISTS tmssapp_trigger_on_check_subtask_state_transition ON tmssapp_SubTask ;
-                                     CREATE TRIGGER tmssapp_trigger_on_check_subtask_state_transition
-                                     BEFORE INSERT OR UPDATE ON tmssapp_SubTask
-                                     FOR EACH ROW EXECUTE PROCEDURE tmssapp_check_subtask_state_transition();'''),
-
-                   # use database triggers to block updates on blueprint tables for immutable fields
-                   migrations.RunSQL('''CREATE OR REPLACE FUNCTION tmssapp_block_scheduling_unit_blueprint_immutable_fields_update()
-                                     RETURNS trigger AS
-                                     $BODY$
-                                     BEGIN
-                                       IF OLD.specifications_template_id <> NEW.specifications_template_id OR
-                                          OLD.name <> NEW.name OR
-                                          OLD.description <> NEW.description THEN
-                                         RAISE EXCEPTION 'ILLEGAL UPDATE OF IMMUTABLE BLUEPRINT FIELD';
-                                       END IF;
-                                     RETURN NEW;
-                                     END;
-                                     $BODY$
-                                     LANGUAGE plpgsql VOLATILE;
-                                     DROP TRIGGER IF EXISTS tmssapp_trigger_block_scheduling_unit_blueprint_immutable_fields_update ON tmssapp_SchedulingUnitBlueprint ;
-                                     CREATE TRIGGER tmssapp_block_scheduling_unit_blueprint_immutable_fields_update
-                                     BEFORE UPDATE ON tmssapp_SchedulingUnitBlueprint
-                                     FOR EACH ROW EXECUTE PROCEDURE tmssapp_block_scheduling_unit_blueprint_immutable_fields_update();
-                                     '''),
-                   migrations.RunSQL('''CREATE OR REPLACE FUNCTION tmssapp_block_task_blueprint_immutable_fields_update()
-                                     RETURNS trigger AS
-                                     $BODY$
-                                     BEGIN
-                                       IF OLD.specifications_doc <> NEW.specifications_doc OR
-                                          OLD.name <> NEW.name OR
-                                          OLD.description <> NEW.description OR
-                                          OLD.short_description <> NEW.short_description OR
-                                          OLD.specifications_template_id <> NEW.specifications_template_id OR
-                                          OLD.scheduling_unit_blueprint_id <> NEW.scheduling_unit_blueprint_id THEN
-                                         RAISE EXCEPTION 'ILLEGAL UPDATE OF IMMUTABLE BLUEPRINT FIELD';
-                                       END IF;
-                                     RETURN NEW;
-                                     END;
-                                     $BODY$
-                                     LANGUAGE plpgsql VOLATILE;
-                                     DROP TRIGGER IF EXISTS tmssapp_trigger_block_task_blueprint_immutable_fields_update ON tmssapp_TaskBlueprint ;
-                                     CREATE TRIGGER tmssapp_block_task_blueprint_immutable_fields_update
-                                     BEFORE UPDATE ON tmssapp_TaskBlueprint
-                                     FOR EACH ROW EXECUTE PROCEDURE tmssapp_block_task_blueprint_immutable_fields_update();
-                                     '''),
-                   migrations.RunSQL('''CREATE OR REPLACE FUNCTION tmssapp_block_task_relation_blueprint_immutable_fields_update()
-                                     RETURNS trigger AS
-                                     $BODY$
-                                     BEGIN
-                                       IF OLD.selection_doc <> NEW.selection_doc OR
-                                          OLD.producer_id <> NEW.producer_id OR
-                                          OLD.consumer_id <> NEW.consumer_id OR
-                                          OLD.input_role_id <> NEW.input_role_id OR
-                                          OLD.output_role_id <> NEW.output_role_id OR
-                                          OLD.input_role_id <> NEW.input_role_id OR
-                                          OLD.selection_template_id <> NEW.selection_template_id THEN
-                                         RAISE EXCEPTION 'ILLEGAL UPDATE OF IMMUTABLE BLUEPRINT FIELD';
-                                       END IF;
-                                     RETURN NEW;
-                                     END;
-                                     $BODY$
-                                     LANGUAGE plpgsql VOLATILE;
-                                     DROP TRIGGER IF EXISTS tmssapp_trigger_block_task_relation_blueprint_immutable_fields_update ON tmssapp_TaskRelationBlueprint ;
-                                     CREATE TRIGGER tmssapp_block_task_relation_blueprint_immutable_fields_update
-                                     BEFORE UPDATE ON tmssapp_TaskRelationBlueprint
-                                     FOR EACH ROW EXECUTE PROCEDURE tmssapp_block_task_relation_blueprint_immutable_fields_update();
-                                     '''),
-                   migrations.RunSQL('''CREATE OR REPLACE FUNCTION tmssapp_block_subtask_immutable_fields_update()
-                                     RETURNS trigger AS
-                                     $BODY$
-                                     BEGIN
-                                       IF OLD.specifications_doc <> NEW.specifications_doc OR
-                                          OLD.primary <> NEW.primary OR
-                                          OLD.task_blueprint_id <> NEW.task_blueprint_id OR
-                                          OLD.specifications_template_id <> NEW.specifications_template_id OR
-                                          OLD.cluster_id <> NEW.cluster_id THEN
-                                         RAISE EXCEPTION 'ILLEGAL UPDATE OF IMMUTABLE SUBTASK FIELD';
-                                       END IF;
-                                     RETURN NEW;
-                                     END;
-                                     $BODY$
-                                     LANGUAGE plpgsql VOLATILE;
-                                     DROP TRIGGER IF EXISTS tmssapp_trigger_block_subtask_immutable_fields_update ON tmssapp_Subtask ;
-                                     CREATE TRIGGER tmssapp_block_subtask_immutable_fields_update
-                                     BEFORE UPDATE ON tmssapp_Subtask
-                                     FOR EACH ROW EXECUTE PROCEDURE tmssapp_block_subtask_immutable_fields_update();
-                                     '''),
-                   migrations.RunPython(populate_choices),
-                   migrations.RunPython(populate_subtask_allowed_state_transitions),
-                   migrations.RunPython(populate_settings),
-                   migrations.RunPython(populate_misc),
-                   migrations.RunPython(populate_resources),
-                   migrations.RunPython(populate_cycles),
-                   migrations.RunPython(populate_projects) ]
-
-"""
-
-
-def execute_and_log(cmd):
-
-    logger.info('COMMAND: %s' % cmd)
-    p = sp.Popen(cmd, shell=True, stdout=sp.PIPE, stderr=sp.PIPE)
-    out, err = p.communicate()
-    if out is not None:
-        logger.info("STDOUT: %s" % out.decode('utf-8').strip())
-    if err is not None:
-        logger.info("STDERR: %s" % err.decode('utf-8').strip())
-
-
-def delete_old_migrations():
-    logger.info('Removing old migrations...')
-
-    files = glob_migrations()
-    for f in [path for path in files if ("initial" in path or "auto" in path or "populate" in path)]:
-        logger.info('Deleting: %s' % f)
-        os.remove(f)
-
-
-def make_django_migrations(dbcredentials=None):
-
-    logger.info('Making Django migrations...')
-    if dbcredentials:
-        os.environ['TMSS_DBCREDENTIALS'] = dbcredentials
-    execute_and_log('/usr/bin/env python3 %s/manage.py makemigrations' % tmss_source_directory)
-
-
-def make_populate_migration():
-
-    logger.info('Making migration for populating database...')
-    last_migration = determine_last_migration()
-    migration = template.format(migration_dependency=last_migration)
-
-    path = tmss_env_directory + relative_migrations_directory + '%s_populate.py' % str(int(last_migration.split('_')[0])+1).zfill(4)
-    logger.info('Writing to: %s' % path)
-    with open(path,'w') as f:
-        f.write(migration)
-
-
-def glob_migrations(directories=(tmss_source_directory, tmss_env_directory)):
-    paths = []
-    for directory in directories:
-        paths += glob(directory + '/' + relative_migrations_directory + '0*_*')
-    return paths
-
-
-def copy_migrations_to_source():
-    logger.info('Copying over migrations to source directory...')
-    files = glob_migrations(directories=[tmss_env_directory])
-    for file in files:
-        logger.info('Copying %s to %s' % (file, tmss_source_directory + '/' + relative_migrations_directory))
-        copy(file, tmss_source_directory + '/' + relative_migrations_directory)
-
-
-def determine_last_migration():
-    logger.info('Determining last migration...')
-    files = glob_migrations()
-    files = [os.path.basename(path) for path in files]
-    f = max(files)
-    last_migration = f.split('.py')[0]
-    logger.info('Determined last migration: %s' % last_migration)
-    return last_migration
-
-
-def remake_migrations(dbcredentials=None):
-    delete_old_migrations()
-    make_django_migrations(dbcredentials)
-    make_populate_migration()
-    copy_migrations_to_source()
-
-
-if __name__ == "__main__":
-
-    logger.setLevel(logging.DEBUG)
-
-    handler = logging.StreamHandler()
-    handler.setLevel(logging.INFO)
-    logger.addHandler(handler)
-
-    parser = argparse.ArgumentParser()
-    parser.add_argument("-C", action="store", dest="dbcredentials", help="use database specified in these dbcredentials")
-    args = parser.parse_args()
-    remake_migrations(args.dbcredentials)
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0004_subtask_error_reason.py b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0004_subtask_error_reason.py
new file mode 100644
index 0000000000000000000000000000000000000000..a784361a44d64cb70e4f95effc9cc722dbeb8ef0
--- /dev/null
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0004_subtask_error_reason.py
@@ -0,0 +1,55 @@
+# Generated by Django 3.0.9 on 2021-10-15 07:51
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tmssapp', '0003_taskblueprint_shortdescription'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='subtask',
+            name='error_reason',
+            field=models.CharField(help_text='Reason why the Subtask went to error.', max_length=200, null=True),
+        ),
+        migrations.RunSQL('''CREATE OR REPLACE FUNCTION tmssapp_block_subtask_immutable_fields_update()
+                          RETURNS trigger AS
+                          $BODY$
+                          BEGIN
+                            IF TG_OP = 'UPDATE' THEN
+                              IF OLD.specifications_doc <> NEW.specifications_doc OR
+                                 OLD.primary <> NEW.primary OR
+                                 OLD.task_blueprint_id <> NEW.task_blueprint_id OR
+                                 OLD.specifications_template_id <> NEW.specifications_template_id OR
+                                 OLD.cluster_id <> NEW.cluster_id THEN
+                                RAISE EXCEPTION 'ILLEGAL UPDATE OF IMMUTABLE SUBTASK FIELD';
+                              END IF;
+
+                              IF OLD.error_reason <> NEW.error_reason OR (OLD.error_reason IS NULL AND NEW.error_reason IS NOT NULL) THEN
+                                IF OLD.error_reason IS NOT NULL THEN
+                                  RAISE EXCEPTION 'subtask.error_reason may only be set once';
+                                END IF;
+                                IF NEW.error_reason IS NOT NULL AND NEW.state_id <> 'error' THEN
+                                  RAISE EXCEPTION 'subtask.error_reason may only be set when state==error';
+                                END IF;
+                              END IF;
+                            END IF;
+
+                            IF TG_OP = 'INSERT' THEN
+                                IF NEW.error_reason IS NOT NULL AND NEW.state_id <> 'error' THEN
+                                  RAISE EXCEPTION 'subtask.error_reason may only be set when state==error';
+                                END IF;
+                            END IF;
+                          RETURN NEW;
+                          END;
+                          $BODY$
+                          LANGUAGE plpgsql VOLATILE;
+                          DROP TRIGGER IF EXISTS tmssapp_block_subtask_immutable_fields_update ON tmssapp_Subtask ;
+                          CREATE TRIGGER tmssapp_block_subtask_immutable_fields_update
+                          BEFORE UPDATE OR INSERT ON tmssapp_Subtask
+                          FOR EACH ROW EXECUTE PROCEDURE tmssapp_block_subtask_immutable_fields_update();
+                          '''),
+    ]
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py
index 7b3200b15cc433f0feaa38cb77c72c8927bcd279..f0a92108015c5d6de0e65b7f415b876ecd25bc63 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py
@@ -152,6 +152,7 @@ class Subtask(BasicCommon, ProjectPropertyMixin, TemplateSchemaMixin):
     cluster = ForeignKey('Cluster', null=True, on_delete=PROTECT, help_text='Where the Subtask is scheduled to run (NULLable).')
     # resource_claim = ForeignKey("ResourceClaim", null=False, on_delete=PROTECT) # todo <-- how is this external reference supposed to work?
     created_or_updated_by_user = ForeignKey(User, null=True, editable=False, on_delete=PROTECT, help_text='The user who created / updated the subtask.')
+    error_reason = CharField(null=True, max_length=200, help_text='Reason why the Subtask went to error.')
     raw_feedback = CharField(null=True, max_length=1048576, help_text='The raw feedback for this Subtask')
     global_identifier = OneToOneField('SIPidentifier', null=False, editable=False, on_delete=PROTECT, help_text='The global unique identifier for LTA SIP.')
     path_to_project = 'task_blueprint__scheduling_unit_blueprint__draft__scheduling_set__project'
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py
index 72c0cf92be4ea0be4c810804f9cb2443e757667c..92746b6c3c340e7b90ed9683c8d60c5e033c1f80 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py
@@ -6,6 +6,7 @@ import logging
 logger = logging.getLogger(__name__)
 
 from rest_framework import serializers
+from rest_framework.exceptions import ValidationError
 from .. import models
 from .widgets import JSONEditorField
 from .common import FloatDurationField, RelationalHyperlinkedModelSerializer, AbstractTemplateSerializer, DynamicRelationalHyperlinkedModelSerializer
@@ -74,7 +75,6 @@ class SubtaskSerializer(DynamicRelationalHyperlinkedModelSerializer):
     input_dataproducts = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='dataproduct-detail')
     output_dataproducts = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='dataproduct-detail')
 
-
     class Meta:
         model = models.Subtask
         fields = '__all__'
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py
index ba36e9feff0c0990626f04413ec4d18c5a94b706..5a314a43ba3841a82c07079f0d44ae0c7db31c9e 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py
@@ -983,8 +983,9 @@ def schedule_subtask(subtask: Subtask) -> Subtask:
                 subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.UNSCHEDULABLE.value)
                 subtask.save()
             else:
-                # set the subtask to state 'ERROR'. TODO: we should annotate in the db what error occurred.
+                # set the subtask to state 'ERROR'.
                 subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.ERROR.value)
+                subtask.error_reason = f'{e}'
                 subtask.save()
         except Exception as e2:
             logger.error(e2)
@@ -2290,6 +2291,7 @@ def cancel_subtask(subtask: Subtask) -> Subtask:
     except Exception as e:
         logger.error("Error while cancelling subtask id=%s type=%s state=%s '%s'", subtask.id, subtask.specifications_template.type.value, subtask.state.value, e)
         subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.ERROR.value)
+        subtask.error_reason = f'{e}'
         subtask.save()
         if isinstance(e, SubtaskCancellingException):
             # we intentionally raised the SubtaskCancellingException, so re-raise it and let the caller handle it
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py
index 5ab6c1e51a1a535c129b8b895f456bf046e20eba..c5adc99347792fe207ec34d8ff8efa0a331201e4 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py
@@ -127,6 +127,7 @@ class SubTaskFilter(property_filters.PropertyFilterSet):
     id_max = filters.NumberFilter(field_name='id', lookup_expr='lte')
     state = filters.ModelMultipleChoiceFilter(field_name='state', queryset=models.SubtaskState.objects.all())
     name = filters.CharFilter(field_name='task_blueprint__scheduling_unit_blueprint__name', lookup_expr='icontains')   # todo: correct name?
+    error_reason = filters.CharFilter(field_name='error_reason', lookup_expr='icontains')
     on_sky_start_time__lt = property_filters.PropertyIsoDateTimeFilter(field_name='on_sky_start_time', lookup_expr='lt')
     on_sky_start_time__gt = property_filters.PropertyIsoDateTimeFilter(field_name='on_sky_start_time', lookup_expr='gt')
     on_sky_stop_time__lt = property_filters.PropertyIsoDateTimeFilter(field_name='on_sky_stop_time', lookup_expr='lt')
diff --git a/SAS/TMSS/backend/test/t_subtasks.py b/SAS/TMSS/backend/test/t_subtasks.py
index 9323947f44de942291823bbf2d8440085f532a4c..13d48f91803829d0950ba0c148be33b572ac72f3 100755
--- a/SAS/TMSS/backend/test/t_subtasks.py
+++ b/SAS/TMSS/backend/test/t_subtasks.py
@@ -754,8 +754,17 @@ class SubtaskAllowedStateTransitionsTest(unittest.TestCase):
 
             # then go to the error state (should be allowed from any of these intermediate states)
             subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.ERROR.value)
+            ERROR_MESSAGE = 'test_helper_method_set_subtask_state_following_allowed_transitions_error_path'
+            subtask.error_reason = ERROR_MESSAGE
             subtask.save()
             self.assertEqual(SubtaskState.Choices.ERROR.value, subtask.state.value)
+            self.assertEqual(ERROR_MESSAGE, subtask.error_reason)
+
+            # overwriting error reason should not be allowed
+            from django.db.utils import InternalError
+            with self.assertRaises(InternalError) as context:
+                subtask.error_reason = "overwriting error reason"
+                subtask.save()
 
     def test_helper_method_set_subtask_state_following_allowed_transitions_cancel_path(self):
         for desired_end_state_value in (SubtaskState.Choices.CANCELLING.value,SubtaskState.Choices.CANCELLED.value):
diff --git a/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py b/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py
index 63dc0bc8747294f21aa90d0a2f69b0adf374c4cf..3a0ca74d9d48e9bcff090432026020fbe7cf8e0a 100755
--- a/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py
+++ b/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py
@@ -739,6 +739,7 @@ class SchedulingUnitBlueprintTest(unittest.TestCase):
         task_blueprint = models.TaskBlueprint.objects.create(**TaskBlueprint_test_data(scheduling_unit_blueprint=scheduling_unit_blueprint))
         subtask = models.Subtask.objects.create(**Subtask_test_data(task_blueprint=task_blueprint))
         subtask.state = models.SubtaskState.objects.get(value='error')  # the derived SUB status is then also error
+        subtask.error_reason = 'test_SchedulingUnitBlueprint_prevents_updating_scheduling_constraints_template_if_not_in_correct_state'
         subtask.save()
 
         scheduling_unit_blueprint.refresh_from_db()
@@ -779,6 +780,7 @@ class SchedulingUnitBlueprintTest(unittest.TestCase):
         task_blueprint = models.TaskBlueprint.objects.create(**TaskBlueprint_test_data(scheduling_unit_blueprint=scheduling_unit_blueprint))
         subtask = models.Subtask.objects.create(**Subtask_test_data(task_blueprint=task_blueprint))
         subtask.state = models.SubtaskState.objects.get(value='error')  # the derived SUB status is then also error
+        subtask.error_reason = 'test_SchedulingUnitBlueprint_prevents_updating_scheduling_constraints_doc_if_not_in_correct_state'
         subtask.save()
 
         scheduling_unit_blueprint.refresh_from_db()
diff --git a/SAS/TMSS/backend/test/test_utils.py b/SAS/TMSS/backend/test/test_utils.py
index e22f2ecb6a37912694fa32e5b7626ac8e87d1c84..10af349b6eb2c4fd5fcc1b500514d6ab94749af6 100644
--- a/SAS/TMSS/backend/test/test_utils.py
+++ b/SAS/TMSS/backend/test/test_utils.py
@@ -111,6 +111,7 @@ def set_subtask_state_following_allowed_transitions(subtask: typing.Union[Subtas
                                                                                                  SubtaskState.Choices.FINISHING.value,
                                                                                                  SubtaskState.Choices.CANCELLING.value):
             subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.ERROR.value)
+            subtask.error_reason = 'set_subtask_state_following_allowed_transitions'
 
         # handle "unsuccessful path" to OBSOLETE end state (via CANCELLED)
         elif desired_state_value == SubtaskState.Choices.OBSOLETE.value: