prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  NoneType Issue
  I dropped a yaml file into a new OU/SubOU and its not working, though it works in other OUs just fine.   Nothing was changed in the file but I am still getting this error, not sure why.
  
  ```
  Traceback (most recent call last):
    File "/root/.pyenv/versions/3.9.12/bin/custodian", line 8, in <module>
      sys.exit(main())
    File "/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/cli.py", line 363, in main
      command(config)
    File "/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/commands.py", line 219, in validate
      structure.validate(data)
    File "/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/structure.py", line 48, in validate
      self.validate_policy(p)
    File "/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/structure.py", line 78, in validate_policy
      for a in p.get('actions', ()):
  TypeError: 'NoneType' object is not iterable
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `c7n/structure.py`
  Content:
  ```
  1 # Copyright The Cloud Custodian Authors.
  2 # SPDX-License-Identifier: Apache-2.0
  3 
  4 import json
  5 
  6 from c7n.exceptions import PolicyValidationError
  7 
  8 
  9 class StructureParser:
  10     """Provide fast validation and inspection of a policy file.
  11 
  12     Intent is to provide more humane validation for top level errors
  13     instead of printing full schema as error message.
  14     """
  15     allowed_file_keys = {'vars', 'policies'}
  16     required_policy_keys = {'name', 'resource'}
  17     allowed_policy_keys = {'name', 'resource', 'title', 'description', 'mode',
  18          'tags', 'max-resources', 'metadata', 'query',
  19          'filters', 'actions', 'source', 'conditions',
  20          # legacy keys subject to deprecation.
  21          'region', 'start', 'end', 'tz', 'max-resources-percent',
  22          'comments', 'comment'}
  23 
  24     def validate(self, data):
  25         if not isinstance(data, dict):
  26             raise PolicyValidationError((
  27                 "Policy file top level data structure "
  28                 "should be a mapping/dict, instead found:%s") % (
  29                     type(data).__name__))
  30         dkeys = set(data.keys())
  31 
  32         extra = dkeys.difference(self.allowed_file_keys)
  33         if extra:
  34             raise PolicyValidationError((
  35                 'Policy files top level keys are %s, found extra: %s' % (
  36                     ', '.join(self.allowed_file_keys),
  37                     ', '.join(extra))))
  38 
  39         if 'policies' not in data:
  40             raise PolicyValidationError("`policies` list missing")
  41 
  42         pdata = data.get('policies', [])
  43         if not isinstance(pdata, list):
  44             raise PolicyValidationError((
  45                 '`policies` key should be an array/list found: %s' % (
  46                     type(pdata).__name__)))
  47         for p in pdata:
  48             self.validate_policy(p)
  49 
  50     def validate_policy(self, p):
  51         if not isinstance(p, dict):
  52             raise PolicyValidationError((
  53                 'policy must be a dictionary/mapping found:%s policy:\n %s' % (
  54                     type(p).__name__, json.dumps(p, indent=2))))
  55         pkeys = set(p)
  56         if self.required_policy_keys.difference(pkeys):
  57             raise PolicyValidationError(
  58                 'policy missing required keys (name, resource) data:\n %s' % (
  59                     json.dumps(p, indent=2)))
  60         if pkeys.difference(self.allowed_policy_keys):
  61             raise PolicyValidationError(
  62                 'policy:%s has unknown keys: %s' % (
  63                     p['name'], ','.join(pkeys.difference(self.allowed_policy_keys))))
  64         if not isinstance(p.get('filters', []), (list, type(None))):
  65             raise PolicyValidationError((
  66                 'policy:%s must use a list for filters found:%s' % (
  67                     p['name'], type(p['filters']).__name__)))
  68         element_types = (dict, str)
  69         for f in p.get('filters', ()):
  70             if not isinstance(f, element_types):
  71                 raise PolicyValidationError((
  72                     'policy:%s filter must be a mapping/dict found:%s' % (
  73                         p.get('name', 'unknown'), type(f).__name__)))
  74         if not isinstance(p.get('actions', []), (list, type(None))):
  75             raise PolicyValidationError((
  76                 'policy:%s must use a list for actions found:%s' % (
  77                     p.get('name', 'unknown'), type(p['actions']).__name__)))
  78         for a in p.get('actions', ()):
  79             if not isinstance(a, element_types):
  80                 raise PolicyValidationError((
  81                     'policy:%s action must be a mapping/dict found:%s' % (
  82                         p.get('name', 'unknown'), type(a).__name__)))
  83 
  84     def get_resource_types(self, data):
  85         resources = set()
  86         for p in data.get('policies', []):
  87             rtype = p['resource']
  88             if '.' not in rtype:
  89                 rtype = 'aws.%s' % rtype
  90             resources.add(rtype)
  91         return resources
  92
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/c7n/structure.py b/c7n/structure.py
  --- a/c7n/structure.py
  +++ b/c7n/structure.py
  @@ -66,7 +66,7 @@
                   'policy:%s must use a list for filters found:%s' % (
                       p['name'], type(p['filters']).__name__)))
           element_types = (dict, str)
  -        for f in p.get('filters', ()):
  +        for f in p.get('filters', ()) or []:
               if not isinstance(f, element_types):
                   raise PolicyValidationError((
                       'policy:%s filter must be a mapping/dict found:%s' % (
  @@ -75,7 +75,7 @@
               raise PolicyValidationError((
                   'policy:%s must use a list for actions found:%s' % (
                       p.get('name', 'unknown'), type(p['actions']).__name__)))
  -        for a in p.get('actions', ()):
  +        for a in p.get('actions', ()) or []:
               if not isinstance(a, element_types):
                   raise PolicyValidationError((
                       'policy:%s action must be a mapping/dict found:%s' % (
  
verification_info: {"golden_diff": "diff --git a/c7n/structure.py b/c7n/structure.py\n--- a/c7n/structure.py\n+++ b/c7n/structure.py\n@@ -66,7 +66,7 @@\n                 'policy:%s must use a list for filters found:%s' % (\n                     p['name'], type(p['filters']).__name__)))\n         element_types = (dict, str)\n-        for f in p.get('filters', ()):\n+        for f in p.get('filters', ()) or []:\n             if not isinstance(f, element_types):\n                 raise PolicyValidationError((\n                     'policy:%s filter must be a mapping/dict found:%s' % (\n@@ -75,7 +75,7 @@\n             raise PolicyValidationError((\n                 'policy:%s must use a list for actions found:%s' % (\n                     p.get('name', 'unknown'), type(p['actions']).__name__)))\n-        for a in p.get('actions', ()):\n+        for a in p.get('actions', ()) or []:\n             if not isinstance(a, element_types):\n                 raise PolicyValidationError((\n                     'policy:%s action must be a mapping/dict found:%s' % (\n", "issue": "NoneType Issue\nI dropped a yaml file into a new OU/SubOU and its not working, though it works in other OUs just fine.   Nothing was changed in the file but I am still getting this error, not sure why.\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/root/.pyenv/versions/3.9.12/bin/custodian\", line 8, in <module>\r\n    sys.exit(main())\r\n  File \"/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/cli.py\", line 363, in main\r\n    command(config)\r\n  File \"/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/commands.py\", line 219, in validate\r\n    structure.validate(data)\r\n  File \"/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/structure.py\", line 48, in validate\r\n    self.validate_policy(p)\r\n  File \"/root/.pyenv/versions/3.9.12/lib/python3.9/site-packages/c7n/structure.py\", line 78, in validate_policy\r\n    for a in p.get('actions', ()):\r\nTypeError: 'NoneType' object is not iterable\r\n```\n", "before_files": [{"content": "# Copyright The Cloud Custodian Authors.\n# SPDX-License-Identifier: Apache-2.0\n\nimport json\n\nfrom c7n.exceptions import PolicyValidationError\n\n\nclass StructureParser:\n    \"\"\"Provide fast validation and inspection of a policy file.\n\n    Intent is to provide more humane validation for top level errors\n    instead of printing full schema as error message.\n    \"\"\"\n    allowed_file_keys = {'vars', 'policies'}\n    required_policy_keys = {'name', 'resource'}\n    allowed_policy_keys = {'name', 'resource', 'title', 'description', 'mode',\n         'tags', 'max-resources', 'metadata', 'query',\n         'filters', 'actions', 'source', 'conditions',\n         # legacy keys subject to deprecation.\n         'region', 'start', 'end', 'tz', 'max-resources-percent',\n         'comments', 'comment'}\n\n    def validate(self, data):\n        if not isinstance(data, dict):\n            raise PolicyValidationError((\n                \"Policy file top level data structure \"\n                \"should be a mapping/dict, instead found:%s\") % (\n                    type(data).__name__))\n        dkeys = set(data.keys())\n\n        extra = dkeys.difference(self.allowed_file_keys)\n        if extra:\n            raise PolicyValidationError((\n                'Policy files top level keys are %s, found extra: %s' % (\n                    ', '.join(self.allowed_file_keys),\n                    ', '.join(extra))))\n\n        if 'policies' not in data:\n            raise PolicyValidationError(\"`policies` list missing\")\n\n        pdata = data.get('policies', [])\n        if not isinstance(pdata, list):\n            raise PolicyValidationError((\n                '`policies` key should be an array/list found: %s' % (\n                    type(pdata).__name__)))\n        for p in pdata:\n            self.validate_policy(p)\n\n    def validate_policy(self, p):\n        if not isinstance(p, dict):\n            raise PolicyValidationError((\n                'policy must be a dictionary/mapping found:%s policy:\\n %s' % (\n                    type(p).__name__, json.dumps(p, indent=2))))\n        pkeys = set(p)\n        if self.required_policy_keys.difference(pkeys):\n            raise PolicyValidationError(\n                'policy missing required keys (name, resource) data:\\n %s' % (\n                    json.dumps(p, indent=2)))\n        if pkeys.difference(self.allowed_policy_keys):\n            raise PolicyValidationError(\n                'policy:%s has unknown keys: %s' % (\n                    p['name'], ','.join(pkeys.difference(self.allowed_policy_keys))))\n        if not isinstance(p.get('filters', []), (list, type(None))):\n            raise PolicyValidationError((\n                'policy:%s must use a list for filters found:%s' % (\n                    p['name'], type(p['filters']).__name__)))\n        element_types = (dict, str)\n        for f in p.get('filters', ()):\n            if not isinstance(f, element_types):\n                raise PolicyValidationError((\n                    'policy:%s filter must be a mapping/dict found:%s' % (\n                        p.get('name', 'unknown'), type(f).__name__)))\n        if not isinstance(p.get('actions', []), (list, type(None))):\n            raise PolicyValidationError((\n                'policy:%s must use a list for actions found:%s' % (\n                    p.get('name', 'unknown'), type(p['actions']).__name__)))\n        for a in p.get('actions', ()):\n            if not isinstance(a, element_types):\n                raise PolicyValidationError((\n                    'policy:%s action must be a mapping/dict found:%s' % (\n                        p.get('name', 'unknown'), type(a).__name__)))\n\n    def get_resource_types(self, data):\n        resources = set()\n        for p in data.get('policies', []):\n            rtype = p['resource']\n            if '.' not in rtype:\n                rtype = 'aws.%s' % rtype\n            resources.add(rtype)\n        return resources\n", "path": "c7n/structure.py"}], "after_files": [{"content": "# Copyright The Cloud Custodian Authors.\n# SPDX-License-Identifier: Apache-2.0\n\nimport json\n\nfrom c7n.exceptions import PolicyValidationError\n\n\nclass StructureParser:\n    \"\"\"Provide fast validation and inspection of a policy file.\n\n    Intent is to provide more humane validation for top level errors\n    instead of printing full schema as error message.\n    \"\"\"\n    allowed_file_keys = {'vars', 'policies'}\n    required_policy_keys = {'name', 'resource'}\n    allowed_policy_keys = {'name', 'resource', 'title', 'description', 'mode',\n         'tags', 'max-resources', 'metadata', 'query',\n         'filters', 'actions', 'source', 'conditions',\n         # legacy keys subject to deprecation.\n         'region', 'start', 'end', 'tz', 'max-resources-percent',\n         'comments', 'comment'}\n\n    def validate(self, data):\n        if not isinstance(data, dict):\n            raise PolicyValidationError((\n                \"Policy file top level data structure \"\n                \"should be a mapping/dict, instead found:%s\") % (\n                    type(data).__name__))\n        dkeys = set(data.keys())\n\n        extra = dkeys.difference(self.allowed_file_keys)\n        if extra:\n            raise PolicyValidationError((\n                'Policy files top level keys are %s, found extra: %s' % (\n                    ', '.join(self.allowed_file_keys),\n                    ', '.join(extra))))\n\n        if 'policies' not in data:\n            raise PolicyValidationError(\"`policies` list missing\")\n\n        pdata = data.get('policies', [])\n        if not isinstance(pdata, list):\n            raise PolicyValidationError((\n                '`policies` key should be an array/list found: %s' % (\n                    type(pdata).__name__)))\n        for p in pdata:\n            self.validate_policy(p)\n\n    def validate_policy(self, p):\n        if not isinstance(p, dict):\n            raise PolicyValidationError((\n                'policy must be a dictionary/mapping found:%s policy:\\n %s' % (\n                    type(p).__name__, json.dumps(p, indent=2))))\n        pkeys = set(p)\n        if self.required_policy_keys.difference(pkeys):\n            raise PolicyValidationError(\n                'policy missing required keys (name, resource) data:\\n %s' % (\n                    json.dumps(p, indent=2)))\n        if pkeys.difference(self.allowed_policy_keys):\n            raise PolicyValidationError(\n                'policy:%s has unknown keys: %s' % (\n                    p['name'], ','.join(pkeys.difference(self.allowed_policy_keys))))\n        if not isinstance(p.get('filters', []), (list, type(None))):\n            raise PolicyValidationError((\n                'policy:%s must use a list for filters found:%s' % (\n                    p['name'], type(p['filters']).__name__)))\n        element_types = (dict, str)\n        for f in p.get('filters', ()) or []:\n            if not isinstance(f, element_types):\n                raise PolicyValidationError((\n                    'policy:%s filter must be a mapping/dict found:%s' % (\n                        p.get('name', 'unknown'), type(f).__name__)))\n        if not isinstance(p.get('actions', []), (list, type(None))):\n            raise PolicyValidationError((\n                'policy:%s must use a list for actions found:%s' % (\n                    p.get('name', 'unknown'), type(p['actions']).__name__)))\n        for a in p.get('actions', ()) or []:\n            if not isinstance(a, element_types):\n                raise PolicyValidationError((\n                    'policy:%s action must be a mapping/dict found:%s' % (\n                        p.get('name', 'unknown'), type(a).__name__)))\n\n    def get_resource_types(self, data):\n        resources = set()\n        for p in data.get('policies', []):\n            rtype = p['resource']\n            if '.' not in rtype:\n                rtype = 'aws.%s' % rtype\n            resources.add(rtype)\n        return resources\n", "path": "c7n/structure.py"}]}