diff --git a/controllers/solutions.php b/controllers/solutions.php
index c29663f28b633f3263794cbd038675fb35a9dc87..b37b5405cccae0a70dac976b3a7fed5faf54308a 100644
--- a/controllers/solutions.php
+++ b/controllers/solutions.php
@@ -1553,10 +1553,10 @@ class SolutionsController extends StudipController
                 $exercise_points  = (float) $exercise_ref->points;
                 $exercise_average = 0;
                 $exercise_correct = 0;
-                $exercise_items   = [];
-                $exercise_items_c = [];
 
                 $exercise_item_count = $exercise->itemCount();
+                $exercise_items      = array_fill(0, $exercise_item_count, 0);
+                $exercise_items_c    = array_fill(0, $exercise_item_count, 0);
 
                 $query = "SELECT vips_solution.* FROM vips_solution
                           LEFT JOIN seminar_user USING(user_id)
@@ -1814,6 +1814,8 @@ function participants_overview_data($course_id, $param_user_id, $display = null,
         'blocks'    => [],
         'exams'     => []
     ];
+    $overall_points = 0;
+    $overall_weighting = 0;
 
     // each assignment
     foreach ($result as $row) {
@@ -1974,11 +1976,13 @@ function participants_overview_data($course_id, $param_user_id, $display = null,
                             'weighting' => $weighted_percent
                         ];
 
+                        if (!isset($participants[$member_id]['overall'])) {
+                            $participants[$member_id]['overall'] = ['points' => 0, 'weighting' => 0];
+                        }
+
                         // sum up overall points and weighted percent
-                        $participants[$member_id]['overall']['points']          += $reached_points;
-                        $participants[$member_id]['overall']['points_tests']    += $reached_points;
-                        $participants[$member_id]['overall']['weighting']       += $weighted_percent;
-                        $participants[$member_id]['overall']['weighting_tests'] += $weighted_percent;
+                        $participants[$member_id]['overall']['points']    += $reached_points;
+                        $participants[$member_id]['overall']['weighting'] += $weighted_percent;
                     }
                 }
             }
@@ -1990,16 +1994,22 @@ function participants_overview_data($course_id, $param_user_id, $display = null,
                     if (!isset($participants[$member_id]['items']['tests_seen'][$assignment_id])) {
                         $participants[$member_id]['items']['tests_seen'][$assignment_id] = true;
 
+                        if (!isset($participants[$member_id]['items']['blocks'][$item_id])) {
+                            $participants[$member_id]['items']['blocks'][$item_id] = ['points' => 0, 'percent' => 0, 'weighting' => 0];
+                        }
+
                         // store reached points, percent and weighted percent for this item, for each group member
                         $participants[$member_id]['items']['blocks'][$item_id]['points']    += $reached_points;
                         $participants[$member_id]['items']['blocks'][$item_id]['percent']   += $percent;
                         $participants[$member_id]['items']['blocks'][$item_id]['weighting'] += $weighted_percent;
 
+                        if (!isset($participants[$member_id]['overall'])) {
+                            $participants[$member_id]['overall'] = ['points' => 0, 'weighting' => 0];
+                        }
+
                         // sum up overall points and weighted percent
-                        $participants[$member_id]['overall']['points']           += $reached_points;
-                        $participants[$member_id]['overall']['points_blocks']    += $reached_points;
-                        $participants[$member_id]['overall']['weighting']        += $weighted_percent;
-                        $participants[$member_id]['overall']['weighting_blocks'] += $weighted_percent;
+                        $participants[$member_id]['overall']['points']    += $reached_points;
+                        $participants[$member_id]['overall']['weighting'] += $weighted_percent;
                     }
                 }
             }
@@ -2014,11 +2024,13 @@ function participants_overview_data($course_id, $param_user_id, $display = null,
                     'weighting' => $weighted_percent
                 ];
 
+                if (!isset($participants[$user_id]['overall'])) {
+                    $participants[$user_id]['overall'] = ['points' => 0, 'weighting' => 0];
+                }
+
                 // sum up overall points and weighted percent
-                $participants[$user_id]['overall']['points']          += $reached_points;
-                $participants[$user_id]['overall']['points_exams']    += $reached_points;
-                $participants[$user_id]['overall']['weighting']       += $weighted_percent;
-                $participants[$user_id]['overall']['weighting_exams'] += $weighted_percent;
+                $participants[$user_id]['overall']['points']    += $reached_points;
+                $participants[$user_id]['overall']['weighting'] += $weighted_percent;
             }
         }
     }
@@ -2093,15 +2105,17 @@ function participants_overview_data($course_id, $param_user_id, $display = null,
         foreach ($participants as $user_id => $participant) {
             $participants[$user_id]['grade'] = '5,0';
 
-            foreach ($settings->VIPS_COURSE_GRADES as $g) {
-                $grade     = $g['grade'];
-                $percent   = $g['percent'];
-                $comment   = $g['comment'];
+            if (isset($participant['overall'])) {
+                foreach ($settings->VIPS_COURSE_GRADES as $g) {
+                    $grade     = $g['grade'];
+                    $percent   = $g['percent'];
+                    $comment   = $g['comment'];
 
-                if ($participant['overall']['weighting'] >= $percent) {
-                    $participants[$user_id]['grade']         = $grade;
-                    $participants[$user_id]['grade_comment'] = $comment;
-                    break;
+                    if ($participant['overall']['weighting'] >= $percent) {
+                        $participants[$user_id]['grade']         = $grade;
+                        $participants[$user_id]['grade_comment'] = $comment;
+                        break;
+                    }
                 }
             }
         }
diff --git a/exercises/Exercise.php b/exercises/Exercise.php
index b20c7e6e6dee7772f93908bd058d90268ef91528..b7e82c6211959ff6cc704fd6bfd1816c892fab0b 100644
--- a/exercises/Exercise.php
+++ b/exercises/Exercise.php
@@ -418,7 +418,7 @@ abstract class Exercise extends SimpleORMap
         $template = VipsPlugin::$template_factory->open('exercises/' . $this->type . '/' . $view);
         $template->exercise = $this;
         $template->solution = $solution;
-        $template->response = $solution->response;
+        $template->response = $solution ? $solution->response : null;
         $template->evaluation_mode = $assignment->options['evaluation_mode'];
 
         return $template;
diff --git a/exercises/algebraq/parser.php b/exercises/algebraq/parser.php
index 93274bf87d654643d17d81aaedce0636d088fc57..142482aae6e97118a3d1c4cb2b786bfaffe186e3 100644
--- a/exercises/algebraq/parser.php
+++ b/exercises/algebraq/parser.php
@@ -625,7 +625,7 @@ class qtype_algebra_parser_variable extends qtype_algebra_parser_term {
             // Extract the remaining characters for use as the subscript
             $this->_subscript=substr($text,strlen($m[1]));
             // If the first letter of the subscript is an underscore then remove it
-            if($this->_subscript[0] == '_') {
+            if($this->_subscript != '' && $this->_subscript[0] == '_') {
                 $this->_subscript=substr($this->_subscript,1);
             }
             // Call the base class constructor with the variable text set to the combination of the
@@ -641,7 +641,7 @@ class qtype_algebra_parser_variable extends qtype_algebra_parser_term {
             // Now set the subscript to the remaining letters
             $this->_subscript=substr($text,1);
             // If the first letter of the subscript is an underscore then remove it
-            if($this->_subscript[0] == '_') {
+            if($this->_subscript != '' && $this->_subscript[0] == '_') {
                 $this->_subscript=substr($this->_subscript,1);
             }
             // Call the base class constructor with the variable text set to the combination of the
diff --git a/exercises/cloze_exercise.php b/exercises/cloze_exercise.php
index 9843971bd2acc53c7a55a633d9b046f51b375c87..7ba11cafcaa68ee5fb15c346238ca28898a24d42 100644
--- a/exercises/cloze_exercise.php
+++ b/exercises/cloze_exercise.php
@@ -304,7 +304,8 @@ class cloze_exercise extends Exercise
         $result = [];
 
         $response = $solution->response;
-        $ignorecase = $this->task['compare'] === 'ignorecase';
+        $ignorecase = isset($this->task['compare']) && $this->task['compare'] === 'ignorecase';
+        $numeric = isset($this->task['compare']) && $this->task['compare'] === 'numeric';
 
         foreach ($this->task['answers'] as $blank => $answer) {
             $student_answer = normalizeText($response[$blank], $ignorecase);
@@ -313,7 +314,7 @@ class cloze_exercise extends Exercise
             $safe = $this->interactionType() !== 'input';
 
             foreach ($answer as $option) {  // different answer options
-                if ($this->task['compare'] === 'numeric' && $student_answer !== '') {
+                if ($numeric && $student_answer !== '') {
                     $correct = normalizeFloat($option['text'], $correct_unit);
                     $student = normalizeFloat($response[$blank], $student_unit);
 
diff --git a/exercises/sc_exercise.php b/exercises/sc_exercise.php
index 67eb928254fc5c8c09e0bc3474b58870d72dab58..b19a27d95583ebd5d0b13177ee1665eb2a61040b 100644
--- a/exercises/sc_exercise.php
+++ b/exercises/sc_exercise.php
@@ -245,7 +245,7 @@ class sc_exercise extends Exercise
         $template = parent::getViewTemplate($view, $solution, $assignment, $user_id);
 
         if (isset($this->options['optional']) && $this->options['optional']) {
-            $template->optional_answer = [-1 => ['text' => _vips('keine Antwort')]];
+            $template->optional_answer = [-1 => ['text' => _vips('keine Antwort'), 'score' => 0]];
         } else {
             $template->optional_answer = [];
         }
diff --git a/exercises/tb_exercise.php b/exercises/tb_exercise.php
index b4910989eed6d0b5871faf894c6750b0999fb90e..950c21de51f4b5a7cdaa675639ec76fe484dd7e2 100644
--- a/exercises/tb_exercise.php
+++ b/exercises/tb_exercise.php
@@ -117,6 +117,14 @@ class tb_exercise extends Exercise
         return $result;
     }
 
+    /**
+     * Return the default response when there is no existing solution.
+     */
+    public function defaultResponse()
+    {
+        return [$this->task['template']];
+    }
+
     /**
      * Return the solution of the student from the request POST data.
      *
diff --git a/views/exercises/cloze_exercise/edit.php b/views/exercises/cloze_exercise/edit.php
index 38073e5cd1509365bcbf436f87e069bd0c7c9ccc..485cf97b72d5bc551628cc112c1e7ffe393bc902 100644
--- a/views/exercises/cloze_exercise/edit.php
+++ b/views/exercises/cloze_exercise/edit.php
@@ -63,7 +63,7 @@
         <?= _vips('Erlaubte relative Abweichung vom korrekten Wert') ?>
         <br>
         <input type="text" class="size-s" style="display: inline; text-align: right;"
-               name="epsilon" value="<?= sprintf('%g', $exercise->task['epsilon'] * 100) ?>"> %
+               name="epsilon" value="<?= isset($exercise->task['epsilon']) ? sprintf('%g', $exercise->task['epsilon'] * 100) : '0' ?>"> %
     </label>
 
     <label>
@@ -72,7 +72,7 @@
 
         <select name="input_width" style="display: inline; width: auto;" <?= isset($exercise->task['input_width']) ? '' : 'disabled' ?>>
             <? foreach ([_vips('kurz'), _vips('mittel'), _vips('lang'), _vips('maximal')] as $key => $label): ?>
-                <option value="<?= $key ?>" <?= $exercise->task['input_width'] == $key ? 'selected' : '' ?>>
+                <option value="<?= $key ?>" <?= isset($exercise->task['input_width']) && $exercise->task['input_width'] == $key ? 'selected' : '' ?>>
                     <?= htmlReady($label) ?>
                 </option>
             <? endforeach ?>
diff --git a/views/exercises/flexible_input.php b/views/exercises/flexible_input.php
index fe70b51c802e7c2421945b8a1ca8de5b776a3636..d425a372d27a53797568108bb8a8ecea7974ad99 100644
--- a/views/exercises/flexible_input.php
+++ b/views/exercises/flexible_input.php
@@ -3,14 +3,17 @@
         <? if ($size === 'small'): ?>
             <?= isset($name) ? 'name="'.$name.'"' : (isset($data_name) ? 'data-name="'.$data_name.'"' : '') ?>
         <? endif ?>
-        value="<?= htmlReady($value) ?>">
+        <? if (isset($value)): ?>
+            value="<?= htmlReady($value) ?>"
+        <? endif ?>
+        >
     <div class="large_input">
         <? $wysiwyg = isset($data_name) ? 'wysiwyg-hidden' : 'wysiwyg' ?>
         <textarea class="character_input <?= $wysiwyg ?> size-l" data-editor="removePlugins=studip-quote,studip-settings;toolbar=small"
             <? if ($size === 'large'): ?>
                 <?= isset($name) ? 'name="'.$name.'"' : (isset($data_name) ? 'data-name="'.$data_name.'"' : '') ?>
             <? endif ?>
-        ><?= wysiwygReady($value) ?></textarea>
+        ><?= wysiwygReady(isset($value) ? $value : '') ?></textarea>
     </div>
 </div>
 <input type="image" class="textarea_toggle small_input" src="<?= vips_image_url('expand.svg') ?>" title="<?= _vips('Eingabefeld vergrößern') ?>">
diff --git a/views/exercises/lt_exercise/edit.php b/views/exercises/lt_exercise/edit.php
index 8e85d839ed63f6086f15e6f06c7af2473d8de958..f6beb31b8110c5efe06036d3409b0031c0ffb9ab 100644
--- a/views/exercises/lt_exercise/edit.php
+++ b/views/exercises/lt_exercise/edit.php
@@ -94,5 +94,5 @@
     <?= _vips('Erlaubte relative Abweichung vom korrekten Wert') ?>
     <br>
     <input type="text" class="size-s" style="display: inline; text-align: right;"
-           name="epsilon" value="<?= sprintf('%g', $exercise->task['epsilon'] * 100) ?>"> %
+           name="epsilon" value="<?= isset($exercise->task['epsilon']) ? sprintf('%g', $exercise->task['epsilon'] * 100) : '0' ?>"> %
 </label>
diff --git a/views/exercises/print_exercise.php b/views/exercises/print_exercise.php
index ca5c62fd149b30ce385bf70afd382924d70df4b7..555e0ef0598a9f81aa6621b7062a919e3457a22f 100644
--- a/views/exercises/print_exercise.php
+++ b/views/exercises/print_exercise.php
@@ -23,7 +23,7 @@
 
     <?= $this->render_partial($exercise->getPrintTemplate($solution, $assignment, $user_id)) ?>
 
-    <? if ($solution->student_comment != '') : ?>
+    <? if ($solution && $solution->student_comment != '') : ?>
         <div class="label-text">
             <?= _vips('Bemerkungen zur Lösung:') ?>
         </div>
@@ -32,15 +32,15 @@
     <? endif ?>
 
     <? if ($print_correction): ?>
-        <? if ($solution->corrector_comment != ''): ?>
-            <div class="label-text">
-                <?= _vips('Anmerkung des Korrektors:') ?>
-            </div>
+        <? if ($solution): ?>
+            <? if ($solution->corrector_comment != ''): ?>
+                <div class="label-text">
+                    <?= _vips('Anmerkung des Korrektors:') ?>
+                </div>
 
-            <?= formatReady($solution->corrector_comment) ?>
-        <? endif ?>
+                <?= formatReady($solution->corrector_comment) ?>
+            <? endif ?>
 
-        <? if ($solution): ?>
             <?= $this->render_partial('solutions/feedback_files') ?>
         <? endif ?>
 
diff --git a/views/solutions/assignments_list.php b/views/solutions/assignments_list.php
index 174a6084c5a1f829cfc92086aa3282c62afb087e..e049b51ce359aac16583472aaf07a0bec6161c09 100644
--- a/views/solutions/assignments_list.php
+++ b/views/solutions/assignments_list.php
@@ -48,7 +48,7 @@
         </thead>
 
         <? foreach ($blocks as $block) :?>
-            <? if ($block_assignments[$block->id] || $block->weight !== null): ?>
+            <? if (isset($block_assignments[$block->id]) || $block->weight !== null): ?>
                 <tbody>
                     <? if (count($blocks) > 1): ?>
                         <tr class="header-row">
@@ -75,7 +75,7 @@
                         </tr>
                     <? endif ?>
 
-                    <? if ($block_assignments[$block->id]): ?>
+                    <? if (isset($block_assignments[$block->id])): ?>
                         <? foreach ($block_assignments[$block->id] as $ass): ?>
                             <tr>
                                 <td>
diff --git a/views/solutions/participants_overview.php b/views/solutions/participants_overview.php
index 9f7b287317b5e2eb473704596323bfa6f0a87717..8d6350d4cea43eb839cfbcf443bbfc0368d4571c 100644
--- a/views/solutions/participants_overview.php
+++ b/views/solutions/participants_overview.php
@@ -165,33 +165,41 @@
                 <? foreach ($items as $category => $list) : ?>
                     <? foreach ($list as $item) : ?>
                         <td style="text-align: right; white-space: nowrap;">
-                            <? $percent = $p['items'][$category][$item['id']]['percent']; ?>
-                            <? if ($display == 'points') : ?>
-                                <span<? if (isset($percent)) : ?> title="<?= sprintf('%.1f %%', $percent) ?>"<? endif ?>>
+                            <span
+                                <? if (isset($p['items'][$category][$item['id']]['percent'])) : ?>
+                                    title="<?= sprintf(_vips('absolut: %.1f %%'), $p['items'][$category][$item['id']]['percent']) ?>"
+                                <? endif ?>>
+                                <? if ($display == 'points') : ?>
                                     <? if (isset($p['items'][$category][$item['id']]['points'])) : ?>
                                         <?= sprintf('%.1f', $p['items'][$category][$item['id']]['points']) ?>
                                     <? else : ?>
                                         &ndash;
                                     <? endif ?>
-                                </span>
-                            <? elseif ($display == 'weighting') : ?>
-                                <span<? if (isset($percent)) : ?> title="<?= sprintf(_vips('absolut: %.1f %%'), $percent) ?>"<? endif ?>>
+                                <? elseif ($display == 'weighting') : ?>
                                     <? if (isset($p['items'][$category][$item['id']]['weighting'])) : ?>
                                         <?= sprintf('%.1f %%', $p['items'][$category][$item['id']]['weighting']) ?>
                                     <? else : ?>
                                         &ndash;
                                     <? endif ?>
-                                </span>
-                            <? endif ?>
+                                <? endif ?>
+                            </span>
                         </td>
                     <? endforeach ?>
                 <? endforeach ?>
 
                 <td style="text-align: right; white-space: nowrap;">
                     <? if ($display == 'points') : ?>
-                        <?= sprintf('%.1f', $p['overall']['points']) ?>
+                        <? if (isset($p['overall']['points'])): ?>
+                            <?= sprintf('%.1f', $p['overall']['points']) ?>
+                        <? else: ?>
+                            &ndash;
+                        <? endif ?>
                     <? elseif ($display == 'weighting') : ?>
-                        <?= sprintf('%.1f %%', $p['overall']['weighting']) ?>
+                        <? if (isset($p['overall']['weighting'])): ?>
+                            <?= sprintf('%.1f %%', $p['overall']['weighting']) ?>
+                        <? else: ?>
+                            &ndash;
+                        <? endif ?>
                     <? endif ?>
                 </td>