diff --git a/typo3/sysext/install/Classes/Command/Exception/WizardDoesNotNeedToMakeChangesException.php b/typo3/sysext/install/Classes/Command/Exception/WizardDoesNotNeedToMakeChangesException.php
new file mode 100644
index 0000000000000000000000000000000000000000..063a7d2d5fb45466a7afdaf352da1d44ac78ce5b
--- /dev/null
+++ b/typo3/sysext/install/Classes/Command/Exception/WizardDoesNotNeedToMakeChangesException.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Install\Command\Exception;
+
+use TYPO3\CMS\Install\Exception as Typo3InstallException;
+
+/**
+ * This exception is thrown in UpgradeWizardRunCommand, if a requested wizard exists but does not need to make any changes.
+ *
+ * @internal for use in UpgradeWizardRunCommand only and not part of public API.
+ */
+final class WizardDoesNotNeedToMakeChangesException extends Typo3InstallException {}
diff --git a/typo3/sysext/install/Classes/Command/Exception/WizardMarkedAsDoneException.php b/typo3/sysext/install/Classes/Command/Exception/WizardMarkedAsDoneException.php
new file mode 100644
index 0000000000000000000000000000000000000000..5cff7de6f81b4120d649a45bd4a0d6241f4bf53b
--- /dev/null
+++ b/typo3/sysext/install/Classes/Command/Exception/WizardMarkedAsDoneException.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Install\Command\Exception;
+
+use TYPO3\CMS\Install\Exception as Typo3InstallException;
+
+/**
+ * This exception is thrown in the UpgradeWizardRunCommand, if a requested wizard is already marked as done.
+ *
+ * @internal for use in UpgradeWizardRunCommand only and not part of public API.
+ */
+final class WizardMarkedAsDoneException extends Typo3InstallException {}
diff --git a/typo3/sysext/install/Classes/Command/Exception/WizardNotFoundException.php b/typo3/sysext/install/Classes/Command/Exception/WizardNotFoundException.php
new file mode 100644
index 0000000000000000000000000000000000000000..42e0f424a2a471e4302cf504efd67bf07abec7ea
--- /dev/null
+++ b/typo3/sysext/install/Classes/Command/Exception/WizardNotFoundException.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Install\Command\Exception;
+
+use TYPO3\CMS\Install\Exception as Typo3InstallException;
+
+/**
+ * This exception is thrown in UpgradeWizardRunCommand, if a requested wizard could not be found.
+ *
+ * @internal for use in UpgradeWizardRunCommand only and not part of public API.
+ */
+final class WizardNotFoundException extends Typo3InstallException {}
diff --git a/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php b/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php
index 72713372d98fc5d20e862642c4a3ea4c8d76abd1..289a6125a6693363eab191d71eecd20ec96a3fec 100644
--- a/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php
+++ b/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php
@@ -28,6 +28,9 @@ use TYPO3\CMS\Core\Authentication\CommandLineUserAuthentication;
 use TYPO3\CMS\Core\Configuration\Exception\SettingsWriteException;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Install\Command\Exception\WizardDoesNotNeedToMakeChangesException;
+use TYPO3\CMS\Install\Command\Exception\WizardMarkedAsDoneException;
+use TYPO3\CMS\Install\Command\Exception\WizardNotFoundException;
 use TYPO3\CMS\Install\Service\DatabaseUpgradeWizardsService;
 use TYPO3\CMS\Install\Service\Exception\ConfigurationChangedException;
 use TYPO3\CMS\Install\Service\Exception\SilentConfigurationUpgradeReadonlyException;
@@ -128,60 +131,67 @@ class UpgradeWizardRunCommand extends Command
         $this->output = new SymfonyStyle($input, $output);
         $this->input = $input;
         $this->bootstrap();
+        $wizardToExecute = (string)$input->getArgument('wizardName');
+        if ($wizardToExecute === '') {
+            return $this->runAllWizards();
+        }
 
-        if ($input->getArgument('wizardName')) {
-            $wizardToExecute = $input->getArgument('wizardName');
-            $wizardToExecute = is_string($wizardToExecute) ? $wizardToExecute : '';
-            if ($this->upgradeWizardsService->isWizardDone($wizardToExecute)) {
-                $this->output->note(sprintf('Wizard %s marked as done. Skipped.', $wizardToExecute));
-                $result = Command::SUCCESS;
-            } elseif (($upgradeWizard = $this->getWizard($wizardToExecute)) !== null) {
-                $prerequisitesFulfilled = $this->handlePrerequisites([$upgradeWizard]);
-                if ($prerequisitesFulfilled === true) {
-                    $result = $this->runSingleWizard($upgradeWizard);
-                } else {
-                    $result = Command::FAILURE;
-                }
-            } else {
-                $this->output->error('No such wizard: ' . $wizardToExecute);
-                $result = Command::FAILURE;
-            }
-        } else {
-            $result = $this->runAllWizards();
+        try {
+            $upgradeWizard = $this->getWizard($wizardToExecute);
+        } catch (WizardMarkedAsDoneException|WizardDoesNotNeedToMakeChangesException $e) {
+            $this->output->note($e->getMessage());
+            return Command::SUCCESS;
+        } catch (WizardNotFoundException $e) {
+            $this->output->error($e->getMessage());
+            return Command::FAILURE;
         }
-        return $result;
+
+        $prerequisitesFulfilled = $this->handlePrerequisites([$upgradeWizard]);
+        if ($prerequisitesFulfilled === true) {
+            return $this->runSingleWizard($upgradeWizard);
+        }
+        return Command::FAILURE;
     }
 
     /**
      * Get Wizard instance by class name and identifier
      * Returns null if wizard is already done
      */
-    protected function getWizard(string $identifier): ?UpgradeWizardInterface
+    protected function getWizard(string $identifier): UpgradeWizardInterface
     {
         // already done
         if ($this->upgradeWizardsService->isWizardDone($identifier)) {
-            return null;
+            throw new WizardMarkedAsDoneException(
+                sprintf('Wizard %s already marked as done', $identifier),
+                1713880347
+            );
         }
-
         $wizard = $this->upgradeWizardsService->getUpgradeWizard($identifier);
         if ($wizard === null) {
-            return null;
+            throw new WizardNotFoundException(
+                sprintf('No such wizard: %s', $identifier),
+                1713880629
+            );
         }
 
         if ($wizard instanceof ChattyInterface) {
             $wizard->setOutput($this->output);
         }
-
         if ($wizard->updateNecessary()) {
             return $wizard;
         }
-        if ($wizard instanceof RepeatableInterface) {
-            $this->output->note('Wizard ' . $identifier . ' does not need to make changes.');
-        } else {
-            $this->output->note('Wizard ' . $identifier . ' does not need to make changes. Marking wizard as done.');
+
+        if (!($wizard instanceof RepeatableInterface)) {
             $this->upgradeWizardsService->markWizardAsDone($wizard);
+            throw new WizardMarkedAsDoneException(
+                sprintf('Wizard %s does not need to make changes. Marking wizard as done.', $identifier),
+                1713880485
+            );
         }
-        return null;
+        throw new WizardDoesNotNeedToMakeChangesException(
+            sprintf('Wizard %s does not need to make changes.', $identifier),
+            1713880493
+        );
     }
 
     /**
@@ -279,9 +289,12 @@ class UpgradeWizardRunCommand extends Command
         $returnCode = Command::SUCCESS;
         $wizardInstances = [];
         foreach ($this->upgradeWizardsService->getUpgradeWizardIdentifiers() as $identifier) {
-            $wizardInstances[] = $this->getWizard($identifier);
+            try {
+                $wizardInstances[] = $this->getWizard($identifier);
+            } catch (WizardMarkedAsDoneException|WizardDoesNotNeedToMakeChangesException|WizardNotFoundException) {
+                // NOOP
+            }
         }
-        $wizardInstances = array_filter($wizardInstances);
         if (count($wizardInstances) > 0) {
             $prerequisitesResult = $this->handlePrerequisites($wizardInstances);
             if ($prerequisitesResult === false) {