We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
E2532 does not support TimeoutSecondsPath and HeartbeatSecondsPath
*cfn-lint version: (`cfn-lint --version`)* 0.61.0

*Description of issue.*
I'm getting the E2532 when trying to use the `TimeoutSecondsPath` parameter in a `Task`.

It is mentioned that it is supported both at https://states-language.net/spec.html#statetypes and https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-task-state.html

Example:

```
"run": {
  "Type": "Task",
  "Resource": "arn:aws:states:::ecs:runTask.sync",
  "Parameters": {
    "LaunchType": "FARGATE",
    "Cluster": "arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${BatchCluster}",
    "TaskDefinition.$": "$.taskDefinition"
  }
  "TimeoutSecondsPath": "$.timeout",
  "ResultPath": null,
  "Next": "done"
}
```

Error from the cfn-lint run:
```
E2532 State Machine Definition key (TimeoutSecondsPath) for State (run) of Type (Task) is not valid
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cfnlint/rules/resources/stepfunctions/StateMachine.py`
Content:
```
1 """
2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 SPDX-License-Identifier: MIT-0
4 """
5 import json
6 
7 from cfnlint.rules import CloudFormationLintRule, RuleMatch
8 
9 
10 class StateMachine(CloudFormationLintRule):
11     """Check State Machine Definition"""
12 
13     id = "E2532"
14     shortdesc = "Check State Machine Definition for proper syntax"
15     description = (
16         "Check the State Machine String Definition to make sure its JSON. "
17         "Validate basic syntax of the file to determine validity."
18     )
19     source_url = "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html"
20     tags = ["resources", "stepfunctions"]
21 
22     def __init__(self):
23         """Init"""
24         super().__init__()
25         self.resource_property_types.append("AWS::StepFunctions::StateMachine")
26 
27     def _check_state_json(self, def_json, state_name, path):
28         """Check State JSON Definition"""
29         matches = []
30 
31         # https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-common-fields.html
32         common_state_keys = [
33             "Next",
34             "End",
35             "Type",
36             "Comment",
37             "InputPath",
38             "OutputPath",
39         ]
40         common_state_required_keys = [
41             "Type",
42         ]
43         state_key_types = {
44             "Pass": ["Result", "ResultPath", "Parameters"],
45             "Task": [
46                 "Resource",
47                 "ResultPath",
48                 "ResultSelector",
49                 "Retry",
50                 "Catch",
51                 "TimeoutSeconds",
52                 "Parameters",
53                 "HeartbeatSeconds",
54             ],
55             "Map": [
56                 "MaxConcurrency",
57                 "Iterator",
58                 "ItemsPath",
59                 "ResultPath",
60                 "ResultSelector",
61                 "Retry",
62                 "Catch",
63                 "Parameters",
64             ],
65             "Choice": ["Choices", "Default"],
66             "Wait": ["Seconds", "Timestamp", "SecondsPath", "TimestampPath"],
67             "Succeed": [],
68             "Fail": ["Cause", "Error"],
69             "Parallel": [
70                 "Branches",
71                 "ResultPath",
72                 "ResultSelector",
73                 "Parameters",
74                 "Retry",
75                 "Catch",
76             ],
77         }
78         state_required_types = {
79             "Pass": [],
80             "Task": ["Resource"],
81             "Choice": ["Choices"],
82             "Wait": [],
83             "Succeed": [],
84             "Fail": [],
85             "Parallel": ["Branches"],
86         }
87 
88         for req_key in common_state_required_keys:
89             if req_key not in def_json:
90                 message = f"State Machine Definition required key ({req_key}) for State ({state_name}) is missing"
91                 matches.append(RuleMatch(path, message))
92                 return matches
93 
94         state_type = def_json.get("Type")
95 
96         if state_type in state_key_types:
97             for state_key, _ in def_json.items():
98                 if state_key not in common_state_keys + state_key_types.get(
99                     state_type, []
100                 ):
101                     message = f"State Machine Definition key ({state_key}) for State ({state_name}) of Type ({state_type}) is not valid"
102                     matches.append(RuleMatch(path, message))
103             for req_key in common_state_required_keys + state_required_types.get(
104                 state_type, []
105             ):
106                 if req_key not in def_json:
107                     message = f"State Machine Definition required key ({req_key}) for State ({state_name}) of Type ({state_type}) is missing"
108                     matches.append(RuleMatch(path, message))
109                     return matches
110         else:
111             message = f"State Machine Definition Type ({state_type}) is not valid"
112             matches.append(RuleMatch(path, message))
113 
114         return matches
115 
116     def _check_definition_json(self, def_json, path):
117         """Check JSON Definition"""
118         matches = []
119 
120         top_level_keys = ["Comment", "StartAt", "TimeoutSeconds", "Version", "States"]
121         top_level_required_keys = ["StartAt", "States"]
122         for top_key, _ in def_json.items():
123             if top_key not in top_level_keys:
124                 message = f"State Machine Definition key ({top_key}) is not valid"
125                 matches.append(RuleMatch(path, message))
126 
127         for req_key in top_level_required_keys:
128             if req_key not in def_json:
129                 message = (
130                     f"State Machine Definition required key ({req_key}) is missing"
131                 )
132                 matches.append(RuleMatch(path, message))
133 
134         for state_name, state_value in def_json.get("States", {}).items():
135             matches.extend(self._check_state_json(state_value, state_name, path))
136         return matches
137 
138     def check_value(self, value, path, fail_on_loads=True):
139         """Check Definition Value"""
140         matches = []
141         try:
142             def_json = json.loads(value)
143         # pylint: disable=W0703
144         except Exception as err:
145             if fail_on_loads:
146                 message = f"State Machine Definition needs to be formatted as JSON. Error {err}"
147                 matches.append(RuleMatch(path, message))
148                 return matches
149 
150             self.logger.debug("State Machine definition could not be parsed. Skipping")
151             return matches
152 
153         matches.extend(self._check_definition_json(def_json, path))
154         return matches
155 
156     def check_sub(self, value, path):
157         """Check Sub Object"""
158         matches = []
159         if isinstance(value, list):
160             matches.extend(self.check_value(value[0], path, False))
161         elif isinstance(value, str):
162             matches.extend(self.check_value(value, path, False))
163 
164         return matches
165 
166     def match_resource_properties(self, properties, _, path, cfn):
167         """Check CloudFormation Properties"""
168         matches = []
169 
170         matches.extend(
171             cfn.check_value(
172                 obj=properties,
173                 key="DefinitionString",
174                 path=path[:],
175                 check_value=self.check_value,
176                 check_sub=self.check_sub,
177             )
178         )
179 
180         return matches
181
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cfnlint/rules/resources/stepfunctions/StateMachine.py b/src/cfnlint/rules/resources/stepfunctions/StateMachine.py
--- a/src/cfnlint/rules/resources/stepfunctions/StateMachine.py
+++ b/src/cfnlint/rules/resources/stepfunctions/StateMachine.py
@@ -43,14 +43,18 @@
         state_key_types = {
             "Pass": ["Result", "ResultPath", "Parameters"],
             "Task": [
+                "Credentials",
                 "Resource",
+                "Parameters",
                 "ResultPath",
                 "ResultSelector",
                 "Retry",
                 "Catch",
                 "TimeoutSeconds",
+                "TimeoutSecondsPath",
                 "Parameters",
                 "HeartbeatSeconds",
+                "HeartbeatSecondsPath",
             ],
             "Map": [
                 "MaxConcurrency",

{"golden_diff": "diff --git a/src/cfnlint/rules/resources/stepfunctions/StateMachine.py b/src/cfnlint/rules/resources/stepfunctions/StateMachine.py\n--- a/src/cfnlint/rules/resources/stepfunctions/StateMachine.py\n+++ b/src/cfnlint/rules/resources/stepfunctions/StateMachine.py\n@@ -43,14 +43,18 @@\n         state_key_types = {\n             \"Pass\": [\"Result\", \"ResultPath\", \"Parameters\"],\n             \"Task\": [\n+                \"Credentials\",\n                 \"Resource\",\n+                \"Parameters\",\n                 \"ResultPath\",\n                 \"ResultSelector\",\n                 \"Retry\",\n                 \"Catch\",\n                 \"TimeoutSeconds\",\n+                \"TimeoutSecondsPath\",\n                 \"Parameters\",\n                 \"HeartbeatSeconds\",\n+                \"HeartbeatSecondsPath\",\n             ],\n             \"Map\": [\n                 \"MaxConcurrency\",\n", "issue": "E2532 does not support TimeoutSecondsPath and HeartbeatSecondsPath\n*cfn-lint version: (`cfn-lint --version`)* 0.61.0\r\n\r\n*Description of issue.*\r\nI'm getting the E2532 when trying to use the `TimeoutSecondsPath` parameter in a `Task`.\r\n\r\nIt is mentioned that it is supported both at https://states-language.net/spec.html#statetypes and https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-task-state.html\r\n\r\nExample:\r\n\r\n```\r\n\"run\": {\r\n  \"Type\": \"Task\",\r\n  \"Resource\": \"arn:aws:states:::ecs:runTask.sync\",\r\n  \"Parameters\": {\r\n    \"LaunchType\": \"FARGATE\",\r\n    \"Cluster\": \"arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${BatchCluster}\",\r\n    \"TaskDefinition.$\": \"$.taskDefinition\"\r\n  }\r\n  \"TimeoutSecondsPath\": \"$.timeout\",\r\n  \"ResultPath\": null,\r\n  \"Next\": \"done\"\r\n}\r\n```\r\n\r\nError from the cfn-lint run:\r\n```\r\nE2532 State Machine Definition key (TimeoutSecondsPath) for State (run) of Type (Task) is not valid\r\n```\r\n\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport json\n\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass StateMachine(CloudFormationLintRule):\n    \"\"\"Check State Machine Definition\"\"\"\n\n    id = \"E2532\"\n    shortdesc = \"Check State Machine Definition for proper syntax\"\n    description = (\n        \"Check the State Machine String Definition to make sure its JSON. \"\n        \"Validate basic syntax of the file to determine validity.\"\n    )\n    source_url = \"https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html\"\n    tags = [\"resources\", \"stepfunctions\"]\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super().__init__()\n        self.resource_property_types.append(\"AWS::StepFunctions::StateMachine\")\n\n    def _check_state_json(self, def_json, state_name, path):\n        \"\"\"Check State JSON Definition\"\"\"\n        matches = []\n\n        # https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-common-fields.html\n        common_state_keys = [\n            \"Next\",\n            \"End\",\n            \"Type\",\n            \"Comment\",\n            \"InputPath\",\n            \"OutputPath\",\n        ]\n        common_state_required_keys = [\n            \"Type\",\n        ]\n        state_key_types = {\n            \"Pass\": [\"Result\", \"ResultPath\", \"Parameters\"],\n            \"Task\": [\n                \"Resource\",\n                \"ResultPath\",\n                \"ResultSelector\",\n                \"Retry\",\n                \"Catch\",\n                \"TimeoutSeconds\",\n                \"Parameters\",\n                \"HeartbeatSeconds\",\n            ],\n            \"Map\": [\n                \"MaxConcurrency\",\n                \"Iterator\",\n                \"ItemsPath\",\n                \"ResultPath\",\n                \"ResultSelector\",\n                \"Retry\",\n                \"Catch\",\n                \"Parameters\",\n            ],\n            \"Choice\": [\"Choices\", \"Default\"],\n            \"Wait\": [\"Seconds\", \"Timestamp\", \"SecondsPath\", \"TimestampPath\"],\n            \"Succeed\": [],\n            \"Fail\": [\"Cause\", \"Error\"],\n            \"Parallel\": [\n                \"Branches\",\n                \"ResultPath\",\n                \"ResultSelector\",\n                \"Parameters\",\n                \"Retry\",\n                \"Catch\",\n            ],\n        }\n        state_required_types = {\n            \"Pass\": [],\n            \"Task\": [\"Resource\"],\n            \"Choice\": [\"Choices\"],\n            \"Wait\": [],\n            \"Succeed\": [],\n            \"Fail\": [],\n            \"Parallel\": [\"Branches\"],\n        }\n\n        for req_key in common_state_required_keys:\n            if req_key not in def_json:\n                message = f\"State Machine Definition required key ({req_key}) for State ({state_name}) is missing\"\n                matches.append(RuleMatch(path, message))\n                return matches\n\n        state_type = def_json.get(\"Type\")\n\n        if state_type in state_key_types:\n            for state_key, _ in def_json.items():\n                if state_key not in common_state_keys + state_key_types.get(\n                    state_type, []\n                ):\n                    message = f\"State Machine Definition key ({state_key}) for State ({state_name}) of Type ({state_type}) is not valid\"\n                    matches.append(RuleMatch(path, message))\n            for req_key in common_state_required_keys + state_required_types.get(\n                state_type, []\n            ):\n                if req_key not in def_json:\n                    message = f\"State Machine Definition required key ({req_key}) for State ({state_name}) of Type ({state_type}) is missing\"\n                    matches.append(RuleMatch(path, message))\n                    return matches\n        else:\n            message = f\"State Machine Definition Type ({state_type}) is not valid\"\n            matches.append(RuleMatch(path, message))\n\n        return matches\n\n    def _check_definition_json(self, def_json, path):\n        \"\"\"Check JSON Definition\"\"\"\n        matches = []\n\n        top_level_keys = [\"Comment\", \"StartAt\", \"TimeoutSeconds\", \"Version\", \"States\"]\n        top_level_required_keys = [\"StartAt\", \"States\"]\n        for top_key, _ in def_json.items():\n            if top_key not in top_level_keys:\n                message = f\"State Machine Definition key ({top_key}) is not valid\"\n                matches.append(RuleMatch(path, message))\n\n        for req_key in top_level_required_keys:\n            if req_key not in def_json:\n                message = (\n                    f\"State Machine Definition required key ({req_key}) is missing\"\n                )\n                matches.append(RuleMatch(path, message))\n\n        for state_name, state_value in def_json.get(\"States\", {}).items():\n            matches.extend(self._check_state_json(state_value, state_name, path))\n        return matches\n\n    def check_value(self, value, path, fail_on_loads=True):\n        \"\"\"Check Definition Value\"\"\"\n        matches = []\n        try:\n            def_json = json.loads(value)\n        # pylint: disable=W0703\n        except Exception as err:\n            if fail_on_loads:\n                message = f\"State Machine Definition needs to be formatted as JSON. Error {err}\"\n                matches.append(RuleMatch(path, message))\n                return matches\n\n            self.logger.debug(\"State Machine definition could not be parsed. Skipping\")\n            return matches\n\n        matches.extend(self._check_definition_json(def_json, path))\n        return matches\n\n    def check_sub(self, value, path):\n        \"\"\"Check Sub Object\"\"\"\n        matches = []\n        if isinstance(value, list):\n            matches.extend(self.check_value(value[0], path, False))\n        elif isinstance(value, str):\n            matches.extend(self.check_value(value, path, False))\n\n        return matches\n\n    def match_resource_properties(self, properties, _, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = []\n\n        matches.extend(\n            cfn.check_value(\n                obj=properties,\n                key=\"DefinitionString\",\n                path=path[:],\n                check_value=self.check_value,\n                check_sub=self.check_sub,\n            )\n        )\n\n        return matches\n", "path": "src/cfnlint/rules/resources/stepfunctions/StateMachine.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport json\n\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass StateMachine(CloudFormationLintRule):\n    \"\"\"Check State Machine Definition\"\"\"\n\n    id = \"E2532\"\n    shortdesc = \"Check State Machine Definition for proper syntax\"\n    description = (\n        \"Check the State Machine String Definition to make sure its JSON. \"\n        \"Validate basic syntax of the file to determine validity.\"\n    )\n    source_url = \"https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html\"\n    tags = [\"resources\", \"stepfunctions\"]\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super().__init__()\n        self.resource_property_types.append(\"AWS::StepFunctions::StateMachine\")\n\n    def _check_state_json(self, def_json, state_name, path):\n        \"\"\"Check State JSON Definition\"\"\"\n        matches = []\n\n        # https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-common-fields.html\n        common_state_keys = [\n            \"Next\",\n            \"End\",\n            \"Type\",\n            \"Comment\",\n            \"InputPath\",\n            \"OutputPath\",\n        ]\n        common_state_required_keys = [\n            \"Type\",\n        ]\n        state_key_types = {\n            \"Pass\": [\"Result\", \"ResultPath\", \"Parameters\"],\n            \"Task\": [\n                \"Credentials\",\n                \"Resource\",\n                \"Parameters\",\n                \"ResultPath\",\n                \"ResultSelector\",\n                \"Retry\",\n                \"Catch\",\n                \"TimeoutSeconds\",\n                \"TimeoutSecondsPath\",\n                \"Parameters\",\n                \"HeartbeatSeconds\",\n                \"HeartbeatSecondsPath\",\n            ],\n            \"Map\": [\n                \"MaxConcurrency\",\n                \"Iterator\",\n                \"ItemsPath\",\n                \"ResultPath\",\n                \"ResultSelector\",\n                \"Retry\",\n                \"Catch\",\n                \"Parameters\",\n            ],\n            \"Choice\": [\"Choices\", \"Default\"],\n            \"Wait\": [\"Seconds\", \"Timestamp\", \"SecondsPath\", \"TimestampPath\"],\n            \"Succeed\": [],\n            \"Fail\": [\"Cause\", \"Error\"],\n            \"Parallel\": [\n                \"Branches\",\n                \"ResultPath\",\n                \"ResultSelector\",\n                \"Parameters\",\n                \"Retry\",\n                \"Catch\",\n            ],\n        }\n        state_required_types = {\n            \"Pass\": [],\n            \"Task\": [\"Resource\"],\n            \"Choice\": [\"Choices\"],\n            \"Wait\": [],\n            \"Succeed\": [],\n            \"Fail\": [],\n            \"Parallel\": [\"Branches\"],\n        }\n\n        for req_key in common_state_required_keys:\n            if req_key not in def_json:\n                message = f\"State Machine Definition required key ({req_key}) for State ({state_name}) is missing\"\n                matches.append(RuleMatch(path, message))\n                return matches\n\n        state_type = def_json.get(\"Type\")\n\n        if state_type in state_key_types:\n            for state_key, _ in def_json.items():\n                if state_key not in common_state_keys + state_key_types.get(\n                    state_type, []\n                ):\n                    message = f\"State Machine Definition key ({state_key}) for State ({state_name}) of Type ({state_type}) is not valid\"\n                    matches.append(RuleMatch(path, message))\n            for req_key in common_state_required_keys + state_required_types.get(\n                state_type, []\n            ):\n                if req_key not in def_json:\n                    message = f\"State Machine Definition required key ({req_key}) for State ({state_name}) of Type ({state_type}) is missing\"\n                    matches.append(RuleMatch(path, message))\n                    return matches\n        else:\n            message = f\"State Machine Definition Type ({state_type}) is not valid\"\n            matches.append(RuleMatch(path, message))\n\n        return matches\n\n    def _check_definition_json(self, def_json, path):\n        \"\"\"Check JSON Definition\"\"\"\n        matches = []\n\n        top_level_keys = [\"Comment\", \"StartAt\", \"TimeoutSeconds\", \"Version\", \"States\"]\n        top_level_required_keys = [\"StartAt\", \"States\"]\n        for top_key, _ in def_json.items():\n            if top_key not in top_level_keys:\n                message = f\"State Machine Definition key ({top_key}) is not valid\"\n                matches.append(RuleMatch(path, message))\n\n        for req_key in top_level_required_keys:\n            if req_key not in def_json:\n                message = (\n                    f\"State Machine Definition required key ({req_key}) is missing\"\n                )\n                matches.append(RuleMatch(path, message))\n\n        for state_name, state_value in def_json.get(\"States\", {}).items():\n            matches.extend(self._check_state_json(state_value, state_name, path))\n        return matches\n\n    def check_value(self, value, path, fail_on_loads=True):\n        \"\"\"Check Definition Value\"\"\"\n        matches = []\n        try:\n            def_json = json.loads(value)\n        # pylint: disable=W0703\n        except Exception as err:\n            if fail_on_loads:\n                message = f\"State Machine Definition needs to be formatted as JSON. Error {err}\"\n                matches.append(RuleMatch(path, message))\n                return matches\n\n            self.logger.debug(\"State Machine definition could not be parsed. Skipping\")\n            return matches\n\n        matches.extend(self._check_definition_json(def_json, path))\n        return matches\n\n    def check_sub(self, value, path):\n        \"\"\"Check Sub Object\"\"\"\n        matches = []\n        if isinstance(value, list):\n            matches.extend(self.check_value(value[0], path, False))\n        elif isinstance(value, str):\n            matches.extend(self.check_value(value, path, False))\n\n        return matches\n\n    def match_resource_properties(self, properties, _, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = []\n\n        matches.extend(\n            cfn.check_value(\n                obj=properties,\n                key=\"DefinitionString\",\n                path=path[:],\n                check_value=self.check_value,\n                check_sub=self.check_sub,\n            )\n        )\n\n        return matches\n", "path": "src/cfnlint/rules/resources/stepfunctions/StateMachine.py"}]}