diff --git a/src/components/PluginSettings/PluginModal.tsx b/src/components/PluginSettings/PluginModal.tsx
index 908876f8..970eb525 100644
--- a/src/components/PluginSettings/PluginModal.tsx
+++ b/src/components/PluginSettings/PluginModal.tsx
@@ -67,6 +67,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
     const [tempSettings, setTempSettings] = React.useState<Record<string, any>>({});
 
     const [errors, setErrors] = React.useState<Record<string, boolean>>({});
+    const [saveError, setSaveError] = React.useState<string | null>(null);
 
     const canSubmit = () => Object.values(errors).every(e => !e);
 
@@ -79,11 +80,20 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
         })();
     }, []);
 
-    function saveAndClose() {
+    async function saveAndClose() {
         if (!plugin.options) {
             onClose();
             return;
         }
+
+        if (plugin.beforeSave) {
+            const result = await Promise.resolve(plugin.beforeSave(tempSettings));
+            if (result !== true) {
+                setSaveError(result);
+                return;
+            }
+        }
+
         let restartNeeded = false;
         for (const [key, value] of Object.entries(tempSettings)) {
             const option = plugin.options[key];
@@ -195,28 +205,31 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
                 </Forms.FormSection>
             </ModalContent>
             <ModalFooter>
-                <Flex>
-                    <Button
-                        onClick={onClose}
-                        size={Button.Sizes.SMALL}
-                        color={Button.Colors.RED}
-                    >
-                        Exit Without Saving
-                    </Button>
-                    <Tooltip text="You must fix all errors before saving" shouldShow={!canSubmit()}>
-                        {({ onMouseEnter, onMouseLeave }) => (
-                            <Button
-                                size={Button.Sizes.SMALL}
-                                color={Button.Colors.BRAND}
-                                onClick={saveAndClose}
-                                onMouseEnter={onMouseEnter}
-                                onMouseLeave={onMouseLeave}
-                                disabled={!canSubmit()}
-                            >
-                                Save & Exit
-                            </Button>
-                        )}
-                    </Tooltip>
+                <Flex flexDirection="column" style={{ width: "100%" }}>
+                    <Flex style={{ marginLeft: "auto" }}>
+                        <Button
+                            onClick={onClose}
+                            size={Button.Sizes.SMALL}
+                            color={Button.Colors.RED}
+                        >
+                            Exit Without Saving
+                        </Button>
+                        <Tooltip text="You must fix all errors before saving" shouldShow={!canSubmit()}>
+                            {({ onMouseEnter, onMouseLeave }) => (
+                                <Button
+                                    size={Button.Sizes.SMALL}
+                                    color={Button.Colors.BRAND}
+                                    onClick={saveAndClose}
+                                    onMouseEnter={onMouseEnter}
+                                    onMouseLeave={onMouseLeave}
+                                    disabled={!canSubmit()}
+                                >
+                                    Save & Exit
+                                </Button>
+                            )}
+                        </Tooltip>
+                    </Flex>
+                    {saveError && <Text variant="text-md/semibold" style={{ color: "var(--text-danger)" }}>Error while saving: {saveError}</Text>}
                 </Flex>
             </ModalFooter>
         </ModalRoot>
diff --git a/src/utils/types.ts b/src/utils/types.ts
index 1916f9be..41dd0c1c 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -16,6 +16,8 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
+import { Promisable } from "type-fest";
+
 import { Command } from "../api/Commands";
 
 // exists to export default definePlugin({...})
@@ -75,6 +77,11 @@ interface PluginDef {
      * Optionally provide settings that the user can configure in the Plugins tab of settings.
      */
     options?: Record<string, PluginOptionsItem>;
+    /**
+     * Check that this returns true before allowing a save to complete.
+     * If a string is returned, show the error to the user.
+     */
+    beforeSave?(options: Record<string, any>): Promisable<true | string>;
     /**
      * Allows you to specify a custom Component that will be rendered in your
      * plugin's settings page