# Buggy code
def process_value_type(self, sentinel, value, resource):
    if self.vtype == "normalize":
        return sentinel, value.strip().lower()

    elif self.vtype == "expr":
        sentinel = self.get_resource_value(sentinel, resource)
        return sentinel, value

    elif self.vtype == "integer":
        try:
            value = int(str(value).strip())
        except ValueError:
            value = 0
    elif self.vtype == "size":
        try:
            return sentinel, len(value)
        except TypeError:
            return sentinel, 0
    elif self.vtype == "unique_size":
        try:
            return sentinel, len(set(value))
        except TypeError:
            return sentinel, 0
    elif self.vtype == "swap":
        return value, sentinel
    elif self.vtype == "date":
        return parse_date(sentinel), parse_date(value)
    elif self.vtype == "age":
        if not isinstance(sentinel, datetime.datetime):
            sentinel = datetime.datetime.now(tz=tzutc()) - timedelta(sentinel)
        value = parse_date(value)
        if value is None:
            # compatiblity
            value = 0
        # Reverse the age comparison, we want to compare the value being
        # greater than the sentinel typically. Else the syntax for age
        # comparisons is intuitively wrong.
        return value, sentinel
    elif self.vtype == "cidr":
        s = parse_cidr(sentinel)
        v = parse_cidr(value)
        if isinstance(s, ipaddress._BaseAddress) and isinstance(
            v, ipaddress._BaseNetwork
        ):
            return v, s
        return s, v
    elif self.vtype == "cidr_size":
        cidr = parse_cidr(value)
        if cidr:
            return sentinel, cidr.prefixlen
        return sentinel, 0

    # Allows for expiration filtering, for events in the future as opposed
    # to events in the past which age filtering allows for.
    elif self.vtype == "expiration":
        if not isinstance(sentinel, datetime.datetime):
            sentinel = datetime.datetime.now(tz=tzutc()) + timedelta(sentinel)
        value = parse_date(value)
        if value is None:
            value = 0
        return sentinel, value

    # Allows for comparing version numbers, for things that you expect a minimum version number.
    elif self.vtype == "version":
        s = ComparableVersion(sentinel)
        v = ComparableVersion(value)
        return s, v

    return sentinel, value


# Traceback (KeyError)
$ custodian run -d -v -s out -p run-asg-auto-tag-creator ./auto-tag-creator.yaml
2020-05-06 15:47:07,205: custodian.commands:DEBUG Loaded file ./auto-tag-creator.yaml. Contains 11 policies
2020-05-06 15:47:07,223: custodian.aws:DEBUG using default region:us-west-2 from boto
2020-05-06 15:47:07,778: custodian.commands:ERROR Error while executing policy run-asg-auto-tag-creator, continuing
Traceback (most recent call last):
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/commands.py", line 281, in run
policy()
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/policy.py", line 1056, in __call__
resources = PullMode(self).run()
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/policy.py", line 279, in run
if not self.policy.is_runnable():
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/policy.py", line 906, in is_runnable
return self.conditions.evaluate(event)
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/policy.py", line 843, in evaluate
state = all([f.process([policy_vars], event) for f in self.filters])
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/policy.py", line 843, in <listcomp>
state = all([f.process([policy_vars], event) for f in self.filters])
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/filters/core.py", line 299, in process
return self.process_set(resources, event)
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/filters/core.py", line 314, in process_set
resource_map = {r[rtype_id]: r for r in resources}
File "/Users/tstansell/.local/c7n/lib/python3.7/site-packages/c7n/filters/core.py", line 314, in <dictcomp>
resource_map = {r[rtype_id]: r for r in resources}
KeyError: 'AutoScalingGroupName'

# Fixed code
def process_value_type(self, sentinel, value, resource):
    if self.vtype == "normalize" and isinstance(value, str):
        return sentinel, value.strip().lower()

    elif self.vtype == "expr":
        sentinel = self.get_resource_value(sentinel, resource)
        return sentinel, value

    elif self.vtype == "integer":
        try:
            value = int(str(value).strip())
        except ValueError:
            value = 0
    elif self.vtype == "size":
        try:
            return sentinel, len(value)
        except TypeError:
            return sentinel, 0
    elif self.vtype == "unique_size":
        try:
            return sentinel, len(set(value))
        except TypeError:
            return sentinel, 0
    elif self.vtype == "swap":
        return value, sentinel
    elif self.vtype == "date":
        return parse_date(sentinel), parse_date(value)
    elif self.vtype == "age":
        if not isinstance(sentinel, datetime.datetime):
            sentinel = datetime.datetime.now(tz=tzutc()) - timedelta(sentinel)
        value = parse_date(value)
        if value is None:
            # compatiblity
            value = 0
        # Reverse the age comparison, we want to compare the value being
        # greater than the sentinel typically. Else the syntax for age
        # comparisons is intuitively wrong.
        return value, sentinel
    elif self.vtype == "cidr":
        s = parse_cidr(sentinel)
        v = parse_cidr(value)
        if isinstance(s, ipaddress._BaseAddress) and isinstance(
            v, ipaddress._BaseNetwork
        ):
            return v, s
        return s, v
    elif self.vtype == "cidr_size":
        cidr = parse_cidr(value)
        if cidr:
            return sentinel, cidr.prefixlen
        return sentinel, 0

    # Allows for expiration filtering, for events in the future as opposed
    # to events in the past which age filtering allows for.
    elif self.vtype == "expiration":
        if not isinstance(sentinel, datetime.datetime):
            sentinel = datetime.datetime.now(tz=tzutc()) + timedelta(sentinel)
        value = parse_date(value)
        if value is None:
            value = 0
        return sentinel, value

    # Allows for comparing version numbers, for things that you expect a minimum version number.
    elif self.vtype == "version":
        s = ComparableVersion(sentinel)
        v = ComparableVersion(value)
        return s, v

    return sentinel, value