diff --git a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
index cbcd8186e18f46cb36f51e6d87759782a31a4fa4..f0ce1ced09b016db31e41924bc17a171c49404a0 100644
--- a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
+++ b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
@@ -417,27 +417,24 @@ class Scheduler:
                 last_on_sky_stop_time = observed_or_beyond_scheduling_units.aggregate(Max('on_sky_stop_time'))['on_sky_stop_time__max']
                 lower_bound_start_time = max(lower_bound_start_time, last_on_sky_stop_time + DEFAULT_NEXT_STARTTIME_GAP)
 
-            # upper bound of search window is at least a week later, or up unit latest cycle end time
-            upper_bound_stop_time = max(lower_bound_start_time + timedelta(days=7),
-                                        max([su.latest_possible_cycle_start_time for su in candidate_units]))
+            # upper bound of search window is at least a 24h later, or up unit latest cycle end time
+            upper_bound_stop_time = max(lower_bound_start_time + timedelta(days=1),
+                                        max([su.latest_possible_cycle_stop_time for su in candidate_units]))
 
-            while lower_bound_start_time < upper_bound_stop_time:
+            window_lower_bound_start_time = lower_bound_start_time
+            while window_lower_bound_start_time < upper_bound_stop_time:
                 self._raise_if_triggered()  # interrupts the scheduling loop for a next round
 
-                if not candidate_units:
-                    logger.info("schedule_next_scheduling_unit: no more candidate units...")
-                    break
-
                 try:
                     # no need to irritate user in log files with sub-second scheduling precision
-                    lower_bound_start_time = round_to_second_precision(lower_bound_start_time)
+                    window_lower_bound_start_time = round_to_second_precision(window_lower_bound_start_time)
                     # our sliding window only looks 12 hours ahead
-                    window_upper_bound_stop_time = round_to_second_precision(lower_bound_start_time + timedelta(hours=12))
+                    window_upper_bound_stop_time = round_to_second_precision(window_lower_bound_start_time + timedelta(hours=12))
 
                     # try to find the best next scheduling_unit
                     logger.info("schedule_next_scheduling_unit: searching for best scheduling unit to schedule in window ['%s', '%s']", lower_bound_start_time, window_upper_bound_stop_time)
                     best_scored_scheduling_unit = self.find_best_next_schedulable_unit(candidate_units,
-                                                                                       lower_bound_start_time,
+                                                                                       window_lower_bound_start_time,
                                                                                        window_upper_bound_stop_time)
 
                     if best_scored_scheduling_unit:
@@ -446,7 +443,7 @@ class Scheduler:
                         best_start_time = best_scored_scheduling_unit.start_time
 
                         # make sure we don't start earlier than allowed
-                        assert best_start_time >= lower_bound_start_time, "The computed start_time='%s' should be larger than the search_window's lower_bound='%s', but it's not."%(best_start_time, lower_bound_start_time)
+                        assert best_start_time >= window_lower_bound_start_time, "The computed start_time='%s' should be larger than the search_window's lower_bound='%s', but it's not."%(best_start_time, lower_bound_start_time)
                         # make start_time "look nice" for us humans
                         best_start_time = round_to_second_precision(best_start_time)
 
@@ -455,7 +452,7 @@ class Scheduler:
 
                         return self.try_schedule_unit(best_scored_scheduling_unit.scheduling_unit, best_scored_scheduling_unit.start_time)
                     else:
-                        logger.info("schedule_next_scheduling_unit: no scheduling unit found which could be scheduled in window ['%s', '%s']", lower_bound_start_time, window_upper_bound_stop_time)
+                        logger.info("schedule_next_scheduling_unit: no scheduling unit found which could be scheduled in window ['%s', '%s']", window_lower_bound_start_time, window_upper_bound_stop_time)
 
                 except SubtaskSchedulingException as e:
                     logger.error("Could not schedule scheduling_unit id=%s name='%s'. Error: %s", best_scheduling_unit.id, best_scheduling_unit.name, e)
@@ -475,24 +472,32 @@ class Scheduler:
                             # yep, can run later, so mark it as schedulable again, and let it be handled in a new scheduler-round
                             mark_independent_subtasks_in_scheduling_unit_blueprint_as_schedulable(best_scheduling_unit)
 
-                # nothing was found, or an error occurred.
-                # it may be that in the mean time some scheduling_units are not (dynamically) schedulable anymore, filter those out.
-                for su in candidate_units:
-                    determine_unschedulable_reason_and_mark_unschedulable_if_needed(su, lower_bound_start_time, upper_bound_stop_time, self.search_gridder, raise_if_interruped=self._raise_if_triggered)
-
                 # all units are refreshed and either schedulable or unschedulable.
                 # refresh list of schedulable_units to be considered in next round (only schedulable)
+                for su in candidate_units:
+                    su.refresh_from_db()
                 candidate_units = [su for su in candidate_units if su.status.value==models.SchedulingUnitStatus.Choices.SCHEDULABLE.value]
 
+                if not candidate_units:
+                    logger.info("schedule_next_scheduling_unit: no more candidate units...")
+                    break
+
                 # advance the window
-                min_earliest_possible_start_time = get_min_earliest_possible_start_time(candidate_units, lower_bound_start_time+timedelta(hours=1), lower_bound_start_time+timedelta(hours=25), gridder=self.search_gridder, raise_if_interruped=self._raise_if_triggered)
+                min_earliest_possible_start_time = get_min_earliest_possible_start_time(candidate_units, window_lower_bound_start_time+timedelta(hours=1), window_lower_bound_start_time+timedelta(hours=25), gridder=self.search_gridder, raise_if_interruped=self._raise_if_triggered)
                 if min_earliest_possible_start_time is None:
-                    lower_bound_start_time += timedelta(hours=6)
+                    window_lower_bound_start_time += timedelta(hours=6)
                 else:
-                    lower_bound_start_time = max(min_earliest_possible_start_time, lower_bound_start_time + timedelta(hours=1))
+                    window_lower_bound_start_time = max(min_earliest_possible_start_time, window_lower_bound_start_time + timedelta(hours=1))
 
                 # search again... (while loop) with the remaining schedulable_units and new lower_bound_start_time
 
+        # nothing was found, or an error occurred.
+        # loop over all (remaining) schedulable units, and make them unschedulable for the big search window (if they are unschedulable)
+        # so they are ignored next time.
+        # It's up to the user/operator to tweak their constraints which makes them schedulable again, for a next try.
+        for su in get_dynamically_schedulable_scheduling_units():
+            determine_unschedulable_reason_and_mark_unschedulable_if_needed(su, lower_bound_start_time, upper_bound_stop_time, self.search_gridder, raise_if_interruped=self._raise_if_triggered)
+
         return None
 
     def try_schedule_unit(self, scheduling_unit: models.SchedulingUnitBlueprint, start_time: datetime) -> models.SchedulingUnitBlueprint:
@@ -660,6 +665,10 @@ class Scheduler:
                 logger.log(log_level, "Schedule:")
                 for unit in units_in_schedule:
                     try:
+                        if unit.status.value==models.SchedulingUnitStatus.Choices.SCHEDULABLE.value and not unit.placed:
+                            # skip non-placed schedulable units
+                            continue
+
                         task_center_time, transit_time, offset_to_transit, lowest_elevation, elevation_at_center, elevation_at_transit = get_timestamps_elevations_and_offset_to_transit(unit, unit.scheduled_start_time)
 
                         logger.log(log_level,
diff --git a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py
index 645d169208974ad0a0b047fe34d9fb17e91dd641..2445157e0b84332c3b126e4b7458b91ad9966444 100755
--- a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py
+++ b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py
@@ -74,10 +74,16 @@ class BaseDynamicSchedulingTestCase(unittest.TestCase):
     @classmethod
     def setUpClass(cls) -> None:
         super().setUpClass()
+        cls.cycle = models.Cycle.objects.create(**Cycle_test_data(start=datetime.utcnow()-timedelta(days=1),
+                                                                  stop=datetime.utcnow() + timedelta(days=7)))
+
         # make some re-usable projects with high/low priority
         cls.project_low = models.Project.objects.create(**Project_test_data("dynsched_project_%s rank=%s" % (uuid.uuid4(), models.ProjectRank.LOWEST.value,), rank=models.ProjectRank.LOWEST.value))
         cls.project_medium = models.Project.objects.create(**Project_test_data("dynsched_project_%s rank=%s" % (uuid.uuid4(), models.ProjectRank.DEFAULT.value,), rank=models.ProjectRank.DEFAULT.value))
         cls.project_high = models.Project.objects.create(**Project_test_data("dynsched_project_%s rank=%s"% (uuid.uuid4(), models.ProjectRank.HIGHEST.value,), rank=models.ProjectRank.HIGHEST.value))
+        cls.cycle.projects.set([cls.project_low, cls.project_medium, cls.project_high])
+        cls.cycle.save()
+
         cls.scheduling_set_low = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=cls.project_low))
         cls.scheduling_set_medium = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=cls.project_medium))
         cls.scheduling_set_high = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=cls.project_high))
@@ -1796,11 +1802,11 @@ class TestDynamicScheduling(BaseDynamicSchedulingTestCase):
         for expected_reason_start, expected_specific_reason_part, constraints in (
                 ("constraint time.at='2029-12-31 00:00:00' falls outside of cycle bounds ['2030-01-01 00:00:00', '2030-01-07 00:00:00']", '',  {'scheduler': 'fixed_time', 'time': {'at': (cycle.start - timedelta(hours=24)).isoformat()}}),
                 ("constraint time.at='2029-12-31 00:00:00' falls outside of cycle bounds ['2030-01-01 00:00:00', '2030-01-07 00:00:00']", '',  {'scheduler': 'dynamic', 'time': {'at': (cycle.start - timedelta(hours=24)).isoformat()}}),
-                ("time constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", '',  {'scheduler': 'dynamic', 'time': {'before': (cycle.start - timedelta(hours=24)).isoformat()}}),
-                ("time constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", '',  {'scheduler': 'dynamic', 'time': {'after': (cycle.stop + timedelta(hours=24)).isoformat()}}),
-                ("sky min_elevation constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", "task_name='Observation' station=CS002 target='_target_name_' elevation=",  {'scheduler': 'dynamic', 'sky': {'min_elevation': {'target': 1.57}}}),
+                ("time constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-07 00:00:00", '',  {'scheduler': 'dynamic', 'time': {'before': (cycle.start - timedelta(hours=24)).isoformat()}}),
+                ("time constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-07 00:00:00", '',  {'scheduler': 'dynamic', 'time': {'after': (cycle.stop + timedelta(hours=24)).isoformat()}}),
+                ("sky min_elevation constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-07 00:00:00", "task_name='Observation' station=CS002 target='_target_name_' elevation=",  {'scheduler': 'dynamic', 'sky': {'min_elevation': {'target': 1.57}}}),
                 ("sky min_elevation constraint is not met at 2030-01-01 00:00:00", "task_name='Observation' station=CS002 target='_target_name_' elevation=",  {'scheduler': 'fixed_time', 'sky': {'min_elevation': {'target': 1.57}}, 'time': {'at': '2030-01-01T00:00:00Z'}}),
-                ("sky min_distance constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", 'to body=sun < min_distance=149.9',  {'scheduler': 'dynamic', 'sky': {'min_distance': {'sun': 150 * 3.1415/180.0}}}),
+                ("sky min_distance constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-07 00:00:00", 'to body=sun < min_distance=149.9',  {'scheduler': 'dynamic', 'sky': {'min_distance': {'sun': 150 * 3.1415/180.0}}}),
                 ("sky min_distance constraint is not met at 2030-01-01 00:00:00", 'to body=sun < min_distance=149.9',  {'scheduler': 'fixed_time', 'sky': {'min_distance': {'sun': 150 * 3.1415/180.0}}, 'time': {'at': '2030-01-01T00:00:00Z'}}),
                 ("sky transit_offset constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-01 07:00:00", '',  {'scheduler': 'dynamic', 'sky': {'transit_offset': {'from': -900, 'to': 900}}, 'time': {'between': [{'from': '2030-01-01T00:00:00Z', 'to': '2030-01-01T07:00:00Z'}]}}),
                 ("sky transit_offset constraint is not met at 2030-01-01 00:00:00", '',  {'scheduler': 'fixed_time', 'sky': {'transit_offset': {'from': -900, 'to': 900}}, 'time': {'at': '2030-01-01T00:00:00Z'}}),
@@ -1810,6 +1816,9 @@ class TestDynamicScheduling(BaseDynamicSchedulingTestCase):
                 ("daily constraint is not met at 2030-01-01 11:00:00", '',  {'scheduler': 'fixed_time', 'daily': {'require_night': True }, 'time': {'at': '2030-01-01T11:00:00Z'}}),
                 ("daily constraint is not met anywhere between 2030-01-01 07:00:00 and 2030-01-01 09:00:00", '',  {'scheduler': 'dynamic', 'daily': {'avoid_twilight': True }, 'time': {'between': [{'from': '2030-01-01T07:00:00Z', 'to': '2030-01-01T09:00:00Z'}]}}),
                 ("daily constraint is not met at 2030-01-01 08:00:00", '', {'scheduler': 'fixed_time', 'daily': {'avoid_twilight': True}, 'time': {'at': '2030-01-01T08:00:00Z'}}) ):
+
+            logger.info('---------------------------------------------------------------------\nchecking for expected reason: %s', expected_reason_start)
+
             # reset unit...
             mark_independent_subtasks_in_scheduling_unit_blueprint_as_schedulable(scheduling_unit_blueprint)
             self.assertEqual('', scheduling_unit_blueprint.unschedulable_reason)
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
index 626be79c34a3d8fcc1948f36619a731dfe9b3c0f..f69678410561a5e8a2295d333cecce3114aa8f76 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
@@ -813,7 +813,7 @@ class Project(ProjectPropertyMixin, NamedCommonPK):
         max_cycle_stop = self.cycles.all().aggregate(Max('stop'))['stop__max']
         if max_cycle_stop:
             return max_cycle_stop
-        return datetime.datetime.utcnow().replace(year=datetime.datetime.today().year+1,
+        return datetime.datetime.utcnow().replace(day=datetime.datetime.today().day+7,
                                                   hour=0, minute=0, second=0, microsecond=0)
 
 class ProjectQuota(Model):
@@ -960,7 +960,7 @@ class SchedulingUnitCommonPropertiesMixin:
     @cached_property
     def latest_possible_cycle_start_time(self) -> datetime.datetime:
         '''return the latest possible start time for this unit's project and cycle(s)'''
-        return self.latest_possible_cycle_stop_time - self.specified_main_observation_duration
+        return self.latest_possible_cycle_stop_time - self.specified_observation_duration
 
     @cached_property
     def latest_possible_cycle_stop_time(self) -> datetime.datetime: