We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
E0002 bug when using parameters for DynamoDB AttributeDefinitions
*cfn-lint version: 0.28.2*

*Description of issue.*

Rule E3039 (added in 0.28.0) doesn't support Refs and results in a E0002 error for the template. 

Repeatable with this template snippet:

```
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
    HashKeyName:
        Description: Primary Key Name
        Type: String
        AllowedPattern: '[a-zA-Z0-9]*'
        MinLength: '1'
        MaxLength: '2048'
        ConstraintDescription: must contain only alphanumberic characters

    HashKeyType:
        Description: Primary Key Type
        Type: String
        Default: S
        AllowedPattern: '[S|N]'
        MinLength: '1'
        MaxLength: '1'
        ConstraintDescription: must be either S or N

    RangeKeyName:
        Description: Sort Key Name
        Type: String
        Default: 'NA'
        AllowedPattern: '[a-zA-Z0-9]*'
        MinLength: '0'
        MaxLength: '2048'
        ConstraintDescription: must contain only alphanumberic characters

    RangeKeyType:
        Description: Sort Key Type
        Type: String
        Default: S
        AllowedPattern: '[S|N]'
        MinLength: '0'
        MaxLength: '1'
        ConstraintDescription: must be either S or Ns

Conditions:
    isRangeKeyAvailable: !Not [ !Equals [ !Ref RangeKeyName, 'NA' ] ]

Resources:
    DynamoDBTable:
        DeletionPolicy: Delete
        UpdateReplacePolicy: Delete
        Type: AWS::DynamoDB::Table
        Properties:
            AttributeDefinitions: !If
                - isRangeKeyAvailable
                - - AttributeName: !Ref HashKeyName
                    AttributeType: !Ref HashKeyType
                  - AttributeName: !Ref RangeKeyName
                    AttributeType: !Ref RangeKeyType
                - - AttributeName: !Ref HashKeyName
                    AttributeType: !Ref HashKeyType
            KeySchema: !If
                - isRangeKeyAvailable
                - - AttributeName: !Ref HashKeyName
                    KeyType: HASH
                  - AttributeName: !Ref RangeKeyName
                    KeyType: RANGE
                - - AttributeName: !Ref HashKeyName
                    KeyType: HASH
```


--- 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/dynamodb/AttributeMismatch.py`
Content:
```
1 """
2 Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 SPDX-License-Identifier: MIT-0
4 """
5 import six
6 from cfnlint.decode.node import list_node
7 from cfnlint.rules import CloudFormationLintRule
8 from cfnlint.rules import RuleMatch
9 
10 
11 class AttributeMismatch(CloudFormationLintRule):
12     """Check DynamoDB Attributes"""
13     id = 'E3039'
14     shortdesc = 'AttributeDefinitions / KeySchemas mismatch'
15     description = 'Verify the set of Attributes in AttributeDefinitions and KeySchemas match'
16     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html'
17     tags = ['resources', 'dynamodb']
18 
19     def __init__(self):
20         """Init"""
21         super(AttributeMismatch, self).__init__()
22         self.resource_property_types = ['AWS::DynamoDB::Table']
23 
24     def _get_key_schema_attributes(self, key_schemas_sets):
25         """ Get Key Schema attributes """
26         keys = set()
27 
28         for properties, _ in key_schemas_sets:
29             for key in properties:
30                 attribute_name = key.get_safe('AttributeName', type_t=six.string_types)
31                 if attribute_name:
32                     keys.add(key.get('AttributeName'))
33         return keys
34 
35     def _get_attribute_secondary(self, property_sets):
36         """ Get the key schemas from secondary indexes """
37         keys = set()
38 
39         for properties, _ in property_sets:
40             for index in properties:
41                 keys = keys.union(
42                     self._get_key_schema_attributes(
43                         index.get_safe('KeySchema', list_node([], None, None), [], list)
44                     )
45                 )
46 
47         return keys
48 
49     def check_property_set(self, property_set, path):
50         """ Check a property set """
51         matches = []
52         properties = property_set.get('Object')
53 
54         keys = set()
55         attributes = set()
56 
57         for attribute in properties.get('AttributeDefinitions', []):
58             attribute_name = attribute.get('AttributeName')
59             if isinstance(attribute_name, six.string_types):
60                 attributes.add(attribute.get('AttributeName'))
61             else:
62                 self.logger.info('attribute definitions is not using just strings')
63                 return matches
64         keys = keys.union(
65             self._get_key_schema_attributes(
66                 properties.get_safe('KeySchema', list_node([], None, None), [], list)
67             )
68         )
69         keys = keys.union(self._get_attribute_secondary(
70             properties.get_safe('GlobalSecondaryIndexes', list_node([], None, None), path, list
71                                 )))  # pylint: disable=bad-continuation
72         keys = keys.union(self._get_attribute_secondary(
73             properties.get_safe('LocalSecondaryIndexes', list_node([], None, None), path, list
74                                 )))  # pylint: disable=bad-continuation
75 
76         if attributes != keys:
77             message = 'The set of Attributes in AttributeDefinitions: {0} and KeySchemas: {1} must match at {2}'
78             matches.append(RuleMatch(
79                 path,
80                 message.format(sorted(list(attributes)), sorted(list(keys)), '/'.join(map(str, path)))
81             ))
82 
83         return matches
84 
85     def check(self, properties, path, cfn):
86         """Check itself"""
87         matches = []
88 
89         property_sets = cfn.get_object_without_conditions(properties, path)
90         for property_set in property_sets:
91             matches.extend(self.check_property_set(property_set, path))
92         return matches
93 
94     def match_resource_properties(self, properties, _, path, cfn):
95         """Match for sub properties"""
96         matches = []
97         matches.extend(self.check(properties, path, cfn))
98         return matches
99
```
--- 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/dynamodb/AttributeMismatch.py b/src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py
--- a/src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py
+++ b/src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py
@@ -77,7 +77,8 @@
             message = 'The set of Attributes in AttributeDefinitions: {0} and KeySchemas: {1} must match at {2}'
             matches.append(RuleMatch(
                 path,
-                message.format(sorted(list(attributes)), sorted(list(keys)), '/'.join(map(str, path)))
+                message.format(sorted(list(attributes)), sorted(
+                    list(keys)), '/'.join(map(str, path)))
             ))
 
         return matches
@@ -86,7 +87,8 @@
         """Check itself"""
         matches = []
 
-        property_sets = cfn.get_object_without_conditions(properties, path)
+        property_sets = cfn.get_object_without_conditions(
+            properties, ['AttributeDefinitions', 'KeySchema', 'GlobalSecondaryIndexes', 'LocalSecondaryIndexes'])
         for property_set in property_sets:
             matches.extend(self.check_property_set(property_set, path))
         return matches

{"golden_diff": "diff --git a/src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py b/src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py\n--- a/src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py\n+++ b/src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py\n@@ -77,7 +77,8 @@\n             message = 'The set of Attributes in AttributeDefinitions: {0} and KeySchemas: {1} must match at {2}'\n             matches.append(RuleMatch(\n                 path,\n-                message.format(sorted(list(attributes)), sorted(list(keys)), '/'.join(map(str, path)))\n+                message.format(sorted(list(attributes)), sorted(\n+                    list(keys)), '/'.join(map(str, path)))\n             ))\n \n         return matches\n@@ -86,7 +87,8 @@\n         \"\"\"Check itself\"\"\"\n         matches = []\n \n-        property_sets = cfn.get_object_without_conditions(properties, path)\n+        property_sets = cfn.get_object_without_conditions(\n+            properties, ['AttributeDefinitions', 'KeySchema', 'GlobalSecondaryIndexes', 'LocalSecondaryIndexes'])\n         for property_set in property_sets:\n             matches.extend(self.check_property_set(property_set, path))\n         return matches\n", "issue": "E0002 bug when using parameters for DynamoDB AttributeDefinitions\n*cfn-lint version: 0.28.2*\r\n\r\n*Description of issue.*\r\n\r\nRule E3039 (added in 0.28.0) doesn't support Refs and results in a E0002 error for the template. \r\n\r\nRepeatable with this template snippet:\r\n\r\n```\r\nAWSTemplateFormatVersion: '2010-09-09'\r\n\r\nParameters:\r\n    HashKeyName:\r\n        Description: Primary Key Name\r\n        Type: String\r\n        AllowedPattern: '[a-zA-Z0-9]*'\r\n        MinLength: '1'\r\n        MaxLength: '2048'\r\n        ConstraintDescription: must contain only alphanumberic characters\r\n\r\n    HashKeyType:\r\n        Description: Primary Key Type\r\n        Type: String\r\n        Default: S\r\n        AllowedPattern: '[S|N]'\r\n        MinLength: '1'\r\n        MaxLength: '1'\r\n        ConstraintDescription: must be either S or N\r\n\r\n    RangeKeyName:\r\n        Description: Sort Key Name\r\n        Type: String\r\n        Default: 'NA'\r\n        AllowedPattern: '[a-zA-Z0-9]*'\r\n        MinLength: '0'\r\n        MaxLength: '2048'\r\n        ConstraintDescription: must contain only alphanumberic characters\r\n\r\n    RangeKeyType:\r\n        Description: Sort Key Type\r\n        Type: String\r\n        Default: S\r\n        AllowedPattern: '[S|N]'\r\n        MinLength: '0'\r\n        MaxLength: '1'\r\n        ConstraintDescription: must be either S or Ns\r\n\r\nConditions:\r\n    isRangeKeyAvailable: !Not [ !Equals [ !Ref RangeKeyName, 'NA' ] ]\r\n\r\nResources:\r\n    DynamoDBTable:\r\n        DeletionPolicy: Delete\r\n        UpdateReplacePolicy: Delete\r\n        Type: AWS::DynamoDB::Table\r\n        Properties:\r\n            AttributeDefinitions: !If\r\n                - isRangeKeyAvailable\r\n                - - AttributeName: !Ref HashKeyName\r\n                    AttributeType: !Ref HashKeyType\r\n                  - AttributeName: !Ref RangeKeyName\r\n                    AttributeType: !Ref RangeKeyType\r\n                - - AttributeName: !Ref HashKeyName\r\n                    AttributeType: !Ref HashKeyType\r\n            KeySchema: !If\r\n                - isRangeKeyAvailable\r\n                - - AttributeName: !Ref HashKeyName\r\n                    KeyType: HASH\r\n                  - AttributeName: !Ref RangeKeyName\r\n                    KeyType: RANGE\r\n                - - AttributeName: !Ref HashKeyName\r\n                    KeyType: HASH\r\n```\r\n\n", "before_files": [{"content": "\"\"\"\nCopyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport six\nfrom cfnlint.decode.node import list_node\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\n\nclass AttributeMismatch(CloudFormationLintRule):\n    \"\"\"Check DynamoDB Attributes\"\"\"\n    id = 'E3039'\n    shortdesc = 'AttributeDefinitions / KeySchemas mismatch'\n    description = 'Verify the set of Attributes in AttributeDefinitions and KeySchemas match'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html'\n    tags = ['resources', 'dynamodb']\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super(AttributeMismatch, self).__init__()\n        self.resource_property_types = ['AWS::DynamoDB::Table']\n\n    def _get_key_schema_attributes(self, key_schemas_sets):\n        \"\"\" Get Key Schema attributes \"\"\"\n        keys = set()\n\n        for properties, _ in key_schemas_sets:\n            for key in properties:\n                attribute_name = key.get_safe('AttributeName', type_t=six.string_types)\n                if attribute_name:\n                    keys.add(key.get('AttributeName'))\n        return keys\n\n    def _get_attribute_secondary(self, property_sets):\n        \"\"\" Get the key schemas from secondary indexes \"\"\"\n        keys = set()\n\n        for properties, _ in property_sets:\n            for index in properties:\n                keys = keys.union(\n                    self._get_key_schema_attributes(\n                        index.get_safe('KeySchema', list_node([], None, None), [], list)\n                    )\n                )\n\n        return keys\n\n    def check_property_set(self, property_set, path):\n        \"\"\" Check a property set \"\"\"\n        matches = []\n        properties = property_set.get('Object')\n\n        keys = set()\n        attributes = set()\n\n        for attribute in properties.get('AttributeDefinitions', []):\n            attribute_name = attribute.get('AttributeName')\n            if isinstance(attribute_name, six.string_types):\n                attributes.add(attribute.get('AttributeName'))\n            else:\n                self.logger.info('attribute definitions is not using just strings')\n                return matches\n        keys = keys.union(\n            self._get_key_schema_attributes(\n                properties.get_safe('KeySchema', list_node([], None, None), [], list)\n            )\n        )\n        keys = keys.union(self._get_attribute_secondary(\n            properties.get_safe('GlobalSecondaryIndexes', list_node([], None, None), path, list\n                                )))  # pylint: disable=bad-continuation\n        keys = keys.union(self._get_attribute_secondary(\n            properties.get_safe('LocalSecondaryIndexes', list_node([], None, None), path, list\n                                )))  # pylint: disable=bad-continuation\n\n        if attributes != keys:\n            message = 'The set of Attributes in AttributeDefinitions: {0} and KeySchemas: {1} must match at {2}'\n            matches.append(RuleMatch(\n                path,\n                message.format(sorted(list(attributes)), sorted(list(keys)), '/'.join(map(str, path)))\n            ))\n\n        return matches\n\n    def check(self, properties, path, cfn):\n        \"\"\"Check itself\"\"\"\n        matches = []\n\n        property_sets = cfn.get_object_without_conditions(properties, path)\n        for property_set in property_sets:\n            matches.extend(self.check_property_set(property_set, path))\n        return matches\n\n    def match_resource_properties(self, properties, _, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = []\n        matches.extend(self.check(properties, path, cfn))\n        return matches\n", "path": "src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py"}], "after_files": [{"content": "\"\"\"\nCopyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport six\nfrom cfnlint.decode.node import list_node\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\n\nclass AttributeMismatch(CloudFormationLintRule):\n    \"\"\"Check DynamoDB Attributes\"\"\"\n    id = 'E3039'\n    shortdesc = 'AttributeDefinitions / KeySchemas mismatch'\n    description = 'Verify the set of Attributes in AttributeDefinitions and KeySchemas match'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html'\n    tags = ['resources', 'dynamodb']\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super(AttributeMismatch, self).__init__()\n        self.resource_property_types = ['AWS::DynamoDB::Table']\n\n    def _get_key_schema_attributes(self, key_schemas_sets):\n        \"\"\" Get Key Schema attributes \"\"\"\n        keys = set()\n\n        for properties, _ in key_schemas_sets:\n            for key in properties:\n                attribute_name = key.get_safe('AttributeName', type_t=six.string_types)\n                if attribute_name:\n                    keys.add(key.get('AttributeName'))\n        return keys\n\n    def _get_attribute_secondary(self, property_sets):\n        \"\"\" Get the key schemas from secondary indexes \"\"\"\n        keys = set()\n\n        for properties, _ in property_sets:\n            for index in properties:\n                keys = keys.union(\n                    self._get_key_schema_attributes(\n                        index.get_safe('KeySchema', list_node([], None, None), [], list)\n                    )\n                )\n\n        return keys\n\n    def check_property_set(self, property_set, path):\n        \"\"\" Check a property set \"\"\"\n        matches = []\n        properties = property_set.get('Object')\n\n        keys = set()\n        attributes = set()\n\n        for attribute in properties.get('AttributeDefinitions', []):\n            attribute_name = attribute.get('AttributeName')\n            if isinstance(attribute_name, six.string_types):\n                attributes.add(attribute.get('AttributeName'))\n            else:\n                self.logger.info('attribute definitions is not using just strings')\n                return matches\n        keys = keys.union(\n            self._get_key_schema_attributes(\n                properties.get_safe('KeySchema', list_node([], None, None), [], list)\n            )\n        )\n        keys = keys.union(self._get_attribute_secondary(\n            properties.get_safe('GlobalSecondaryIndexes', list_node([], None, None), path, list\n                                )))  # pylint: disable=bad-continuation\n        keys = keys.union(self._get_attribute_secondary(\n            properties.get_safe('LocalSecondaryIndexes', list_node([], None, None), path, list\n                                )))  # pylint: disable=bad-continuation\n\n        if attributes != keys:\n            message = 'The set of Attributes in AttributeDefinitions: {0} and KeySchemas: {1} must match at {2}'\n            matches.append(RuleMatch(\n                path,\n                message.format(sorted(list(attributes)), sorted(\n                    list(keys)), '/'.join(map(str, path)))\n            ))\n\n        return matches\n\n    def check(self, properties, path, cfn):\n        \"\"\"Check itself\"\"\"\n        matches = []\n\n        property_sets = cfn.get_object_without_conditions(\n            properties, ['AttributeDefinitions', 'KeySchema', 'GlobalSecondaryIndexes', 'LocalSecondaryIndexes'])\n        for property_set in property_sets:\n            matches.extend(self.check_property_set(property_set, path))\n        return matches\n\n    def match_resource_properties(self, properties, _, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = []\n        matches.extend(self.check(properties, path, cfn))\n        return matches\n", "path": "src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py"}]}