From acefab19b270d4ccdbc43c3c40acb50ac57a4b2a Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Sat, 24 May 2025 09:57:58 -0600 Subject: [PATCH] Start Frigate in safe mode when config does not validate --- frigate/__main__.py | 9 ++++++++- frigate/config/config.py | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/frigate/__main__.py b/frigate/__main__.py index 4143f7ae6..a16b25111 100644 --- a/frigate/__main__.py +++ b/frigate/__main__.py @@ -93,7 +93,14 @@ def main() -> None: print("*************************************************************") print("*** End Config Validation Errors ***") print("*************************************************************") - sys.exit(1) + + # attempt to start Frigate in recovery mode + try: + config = FrigateConfig.load(install=True, safe_load=True) + print("Starting Frigate in safe mode.") + except ValidationError: + print("Unable to load minimal Frigate config.") + sys.exit(1) if args.validate_config: print("*************************************************************") print("*** Your config file is valid. ***") diff --git a/frigate/config/config.py b/frigate/config/config.py index 6ec048acd..58427f5d5 100644 --- a/frigate/config/config.py +++ b/frigate/config/config.py @@ -334,6 +334,9 @@ def verify_lpr_and_face( class FrigateConfig(FrigateBaseModel): version: Optional[str] = Field(default=None, title="Current config version.") + safe_mode: bool = Field( + default=False, title="If Frigate should be started in safe mode." + ) # Fields that install global state should be defined first, so that their validators run first. environment_vars: EnvVars = Field( @@ -716,6 +719,7 @@ class FrigateConfig(FrigateBaseModel): @classmethod def load(cls, **kwargs): + """Loads the Frigate config file, runs migrations, and creates the config object.""" config_path = find_config_file() # No configuration file found, create one. @@ -743,7 +747,7 @@ class FrigateConfig(FrigateBaseModel): return FrigateConfig.parse(f, **kwargs) @classmethod - def parse(cls, config, *, is_json=None, **context): + def parse(cls, config, *, is_json=None, safe_load=False, **context): # If config is a file, read its contents. if hasattr(config, "read"): fname = getattr(config, "name", None) @@ -767,6 +771,15 @@ class FrigateConfig(FrigateBaseModel): else: config = yaml.load(config) + # load minimal Frigate config after the full config did not validate + if safe_load: + safe_config = {"safe_mode": True, "cameras": {}, "mqtt": {"enabled": False}} + + # copy over auth and proxy config in case auth needs to be enforced + safe_config["auth"] = config.get("auth", {}) + safe_config["proxy"] = config.get("proxy", {}) + return cls.parse_object(safe_config, **context) + # Validate and return the config dict. return cls.parse_object(config, **context)