Repository: aws-cloudformation/cfn-lint

Issue:
Debug flag not working on cfnlintrc file.
### CloudFormation Lint Version

cfn-lint 1.22.3

### What operating system are you using?

Mac 15.2

### Describe the bug

I'm using the file .cfnlintrc.yaml to configure the tool and when I put the option *debug* it fails with the error:

> Traceback (most recent call last):
>   File "/opt/homebrew/bin/cfn-lint", line 8, in <module>
>     sys.exit(main())
>              ~~~~^^
>   File "/opt/homebrew/Cellar/cfn-lint/1.22.3/libexec/lib/python3.13/site-packages/cfnlint/runner.py", line 455, in main
>     config = ConfigMixIn(sys.argv[1:])
>   File "/opt/homebrew/Cellar/cfn-lint/1.22.3/libexec/lib/python3.13/site-packages/cfnlint/config.py", line 631, in __init__
>     ConfigFileArgs.__init__(
>     ~~~~~~~~~~~~~~~~~~~~~~~^
>         self, config_file=self._get_argument_value("config_file", False, False)
>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>     )
>     ^
>   File "/opt/homebrew/Cellar/cfn-lint/1.22.3/libexec/lib/python3.13/site-packages/cfnlint/config.py", line 79, in __init__
>     self.load()
>     ~~~~~~~~~^^
>   File "/opt/homebrew/Cellar/cfn-lint/1.22.3/libexec/lib/python3.13/site-packages/cfnlint/config.py", line 154, in load
>     self.validate_config(project_config, self.schema)
>     ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "/opt/homebrew/Cellar/cfn-lint/1.22.3/libexec/lib/python3.13/site-packages/cfnlint/config.py", line 182, in validate_config
>     validator.validate(config)
>     ~~~~~~~~~~~~~~~~~~^^^^^^^^
>   File "/opt/homebrew/Cellar/cfn-lint/1.22.3/libexec/lib/python3.13/site-packages/cfnlint/jsonschema/validators.py", line 294, in validate
>     raise error
> cfnlint.jsonschema.exceptions.ValidationError: ("Additional properties are not allowed ('debug' was unexpected)", <unset>, ['debug'], None, (), <unset>, <unset>, <unset>, (), None)

The same symptoms happens for "info: true" and "format: <format_string>". 

### Expected behavior

Run lint with debug enabled

### Reproduction template

.cfnlintrc.yaml
```
templates:
- cicd/templates/cloudformation/**/*.yaml
include_checks:
- I
ignore_checks:
- I1022 # Prefer using Fn::Sub over Fn::Join with an empty delimiter
output_file: "test-output.txt"
regions:
- us-east-1
- us-east-2
debug: true
```

Hints from issue comments:
@kddejong: Two parts to this:
1. Debug is currently not supported by `.cfnlintrc` as [here](https://github.com/aws-cloudformation/cfn-lint/blob/e087f1037b067288e377d197d6b855cd481d6a47/src/cfnlint/config.py#L722-L724). I would need to see if there are any issues with doing this.
2. A failure like this in the `.cfnlintrc` shouldn't cause cfn-lint ot fail with an exception.@unknown: Thanks for quick reply @kddejong.
Any plan to add more flags to `.cfnlintrc`?

It raised this exception and stopped the pipeline

Solution patch:
diff --git a/src/cfnlint/config.py b/src/cfnlint/config.py
index 03846af54..a9f4aa5e4 100644
--- a/src/cfnlint/config.py
+++ b/src/cfnlint/config.py
@@ -313,7 +313,7 @@ class RuleConfigurationAction(argparse.Action):
             setattr(namespace, self.dest, items)
         except Exception:  # pylint: disable=W0703
             parser.print_help()
-            parser.exit()
+            parser.exit(1)
 
 
 class CliArgs:
@@ -331,7 +331,7 @@ class CliArgs:
 
             def error(self, message):
                 self.print_help(sys.stderr)
-                self.exit(32, f"{self.prog}: error: {message}\n")
+                self.exit(1, f"{self.prog}: error: {message}\n")
 
         class ExtendAction(argparse.Action):
             """Support argument types that are lists and can
@@ -620,7 +620,6 @@ class ManualArgs(TypedDict, total=False):
 
 # pylint: disable=too-many-public-methods
 class ConfigMixIn(TemplateArgs, CliArgs, ConfigFileArgs):
-    """Mixin for the Configs"""
 
     def __init__(self, cli_args: list[str] | None = None, **kwargs: Unpack[ManualArgs]):
         self._manual_args = kwargs or ManualArgs()
@@ -721,7 +720,7 @@ class ConfigMixIn(TemplateArgs, CliArgs, ConfigFileArgs):
 
     @property
     def debug(self):
-        return self._get_argument_value("debug", False, False)
+        return self._get_argument_value("debug", False, True)
 
     @property
     def info(self):
diff --git a/src/cfnlint/core.py b/src/cfnlint/core.py
index e1e231d76..899e06cbe 100644
--- a/src/cfnlint/core.py
+++ b/src/cfnlint/core.py
@@ -9,9 +9,10 @@ import os
 from typing import Sequence
 
 from cfnlint.config import _DEFAULT_RULESDIR, ConfigMixIn, ManualArgs
+from cfnlint.exceptions import UnexpectedRuleException
 from cfnlint.match import Match
 from cfnlint.rules import RulesCollection
-from cfnlint.runner import TemplateRunner, UnexpectedRuleException
+from cfnlint.runner import TemplateRunner
 
 
 def get_rules(
diff --git a/src/cfnlint/data/CfnLintCli/config/schema.json b/src/cfnlint/data/CfnLintCli/config/schema.json
index f72fc6189..e87f1234b 100644
--- a/src/cfnlint/data/CfnLintCli/config/schema.json
+++ b/src/cfnlint/data/CfnLintCli/config/schema.json
@@ -58,6 +58,10 @@
    "description": "custom rule file to use",
    "type": "string"
   },
+  "debug": {
+   "description": "Debug mode",
+   "type": "boolean"
+  },
   "ignore_bad_template": {
    "description": "Ignore bad templates",
    "type": "boolean"
diff --git a/src/cfnlint/exceptions.py b/src/cfnlint/exceptions.py
index cedb10369..993106ab0 100644
--- a/src/cfnlint/exceptions.py
+++ b/src/cfnlint/exceptions.py
@@ -1,21 +1,57 @@
-class CfnLintError(Exception):
+class CfnLintExitException(Exception):
     """
-    The base exception class for cfn-lint exceptions.
-    :ivar msg: The descriptive message associated with the error.
+    An exception that is raised to indicate that the CloudFormation linter should exit.
+
+    This exception is used to signal that the linter should exit
+    with a specific exit code, typically indicating the severity
+    of the issues found in the CloudFormation template.
+
+    Attributes:
+        exit_code (int): The exit code to be used when the linter exits.
+
+    Methods:
+        __init__(self, exit_code: int) -> None:
+            Initialize a new CfnLintExitException instance with the specified exit code.
     """
 
-    fmt = "An unspecified error occurred"
+    def __init__(self, msg=None, exit_code=1):
+        """
+        Initialize a new CfnLintExitException instance with the specified exit code.
+
+        Args:
+            exit_code (int): The exit code to be used when the linter exits.
+        """
+        if msg is None:
+            msg = f"process failed with exit code {exit_code}"
+        super().__init__(msg)
+        self.exit_code = exit_code
+
+
+class InvalidRegionException(CfnLintExitException):
+    """
+    An exception that is raised when an invalid AWS region is encountered.
 
-    def __init__(self, **kwargs):
-        msg = self.fmt.format(**kwargs)
-        Exception.__init__(self, msg)
-        self.kwargs = kwargs
+    This exception is raised when the CloudFormation linter encounters a resource
+    or parameter that references an AWS region that is not valid or supported.
+    """
+
+
+class UnexpectedRuleException(CfnLintExitException):
+    """
+    An exception that is raised when an unexpected error occurs while loading rules.
+
+    This exception is raised when the CloudFormation linter encounters an error
+    while attempting to load custom rules or rules from a specified directory or
+    module. This could be due to a variety of reasons, such as a missing file,
+    a syntax error in the rule code, or an issue with the rule implementation.
+    """
 
 
-class DuplicateRuleError(CfnLintError):
+class DuplicateRuleError(CfnLintExitException):
     """
     The data associated with a particular path could not be loaded.
     :ivar data_path: The data path that the user attempted to load.
     """
 
-    fmt = "Rule already included: {rule_id}"
+    def __init__(self, rule_id: str):
+        super().__init__(f"Rule already included: {rule_id}")
diff --git a/src/cfnlint/runner.py b/src/cfnlint/runner.py
index 6b8acabd5..a334fba12 100644
--- a/src/cfnlint/runner.py
+++ b/src/cfnlint/runner.py
@@ -15,6 +15,11 @@ import cfnlint.formatters
 import cfnlint.maintenance
 from cfnlint.config import ConfigMixIn, configure_logging
 from cfnlint.decode.decode import decode
+from cfnlint.exceptions import (
+    CfnLintExitException,
+    InvalidRegionException,
+    UnexpectedRuleException,
+)
 from cfnlint.helpers import REGIONS
 from cfnlint.rules import Match, Rules
 from cfnlint.rules.errors import ConfigError, ParseError, TransformError
@@ -452,55 +457,10 @@ class Runner:
 
 
 def main() -> None:
-    config = ConfigMixIn(sys.argv[1:])
+    try:
+        config = ConfigMixIn(sys.argv[1:])
+    except Exception as e:
+        print(e)
+        sys.exit(1)
     runner = Runner(config)
     runner.cli()
-
-
-class CfnLintExitException(Exception):
-    """
-    An exception that is raised to indicate that the CloudFormation linter should exit.
-
-    This exception is used to signal that the linter should exit
-    with a specific exit code, typically indicating the severity
-    of the issues found in the CloudFormation template.
-
-    Attributes:
-        exit_code (int): The exit code to be used when the linter exits.
-
-    Methods:
-        __init__(self, exit_code: int) -> None:
-            Initialize a new CfnLintExitException instance with the specified exit code.
-    """
-
-    def __init__(self, msg=None, exit_code=1):
-        """
-        Initialize a new CfnLintExitException instance with the specified exit code.
-
-        Args:
-            exit_code (int): The exit code to be used when the linter exits.
-        """
-        if msg is None:
-            msg = f"process failed with exit code {exit_code}"
-        super().__init__(msg)
-        self.exit_code = exit_code
-
-
-class InvalidRegionException(CfnLintExitException):
-    """
-    An exception that is raised when an invalid AWS region is encountered.
-
-    This exception is raised when the CloudFormation linter encounters a resource
-    or parameter that references an AWS region that is not valid or supported.
-    """
-
-
-class UnexpectedRuleException(CfnLintExitException):
-    """
-    An exception that is raised when an unexpected error occurs while loading rules.
-
-    This exception is raised when the CloudFormation linter encounters an error
-    while attempting to load custom rules or rules from a specified directory or
-    module. This could be due to a variety of reasons, such as a missing file,
-    a syntax error in the rule code, or an issue with the rule implementation.
-    """


Test patch:
diff --git a/test/unit/module/config/test_config_file_args.py b/test/unit/module/config/test_config_file_args.py
index 86144086c..2541f599d 100644
--- a/test/unit/module/config/test_config_file_args.py
+++ b/test/unit/module/config/test_config_file_args.py
@@ -8,7 +8,7 @@ from pathlib import Path
 from test.testlib.testcase import BaseTestCase
 from unittest.mock import patch
 
-import cfnlint.config  # pylint: disable=E0401
+import cfnlint.config
 from cfnlint.jsonschema import ValidationError
 
 LOGGER = logging.getLogger("cfnlint")
diff --git a/test/unit/module/runner/test_rule_configuration.py b/test/unit/module/runner/test_rule_configuration.py
index 444ad341e..7a58e8b99 100644
--- a/test/unit/module/runner/test_rule_configuration.py
+++ b/test/unit/module/runner/test_rule_configuration.py
@@ -7,7 +7,8 @@ import os
 from test.testlib.testcase import BaseTestCase
 
 from cfnlint.config import ConfigMixIn
-from cfnlint.runner import Runner, UnexpectedRuleException
+from cfnlint.exceptions import UnexpectedRuleException
+from cfnlint.runner import Runner
 
 
 class TestGetRules(BaseTestCase):