# Buggy code
def render_event_pattern(self):
    event_type = self.data.get("type")
    pattern = self.data.get("pattern")

    payload = {}
    if pattern:
        payload.update(pattern)

    if event_type == "cloudtrail":
        payload["detail-type"] = ["AWS API Call via CloudTrail"]
        self.resolve_cloudtrail_payload(payload)
    if event_type == "cloudtrail":
        if "signin.amazonaws.com" in payload["detail"]["eventSource"]:
            payload["detail-type"] = ["AWS Console Sign In via CloudTrail"]
    elif event_type == "guard-duty":
        payload["source"] = ["aws.guardduty"]
        payload["detail-type"] = ["GuardDuty Finding"]
        if "resource-filter" in self.data:
            payload.update(
                {
                    "detail": {
                        "resource": {"resourceType": [self.data["resource-filter"]]}
                    }
                }
            )
    elif event_type == "ec2-instance-state":
        payload["source"] = ["aws.ec2"]
        payload["detail-type"] = ["EC2 Instance State-change Notification"]
        # Technically could let empty be all events, but likely misconfig
        payload["detail"] = {"state": self.data.get("events", [])}
    elif event_type == "asg-instance-state":
        payload["source"] = ["aws.autoscaling"]
        events = []
        for e in self.data.get("events", []):
            events.append(self.ASG_EVENT_MAPPING.get(e, e))
        payload["detail-type"] = events
    elif event_type == "phd":
        payload["source"] = ["aws.health"]
        if self.data.get("events"):
            payload["detail"] = {"eventTypeCode": list(self.data["events"])}
        if self.data.get("categories", []):
            payload["detail"]["eventTypeCategory"] = self.data["categories"]
    elif event_type == "hub-finding":
        payload["source"] = ["aws.securityhub"]
        payload["detail-type"] = ["Security Hub Findings - Imported"]
    elif event_type == "hub-action":
        payload["source"] = ["aws.securityhub"]
        payload["detail-type"] = [
            "Security Hub Findings - Custom Action",
            "Security Hub Insight Results",
        ]
    elif event_type == "periodic":
        pass
    else:
        raise ValueError("Unknown lambda event source type: %s" % event_type)
    if not payload:
        return None
    if self.data.get("pattern"):
        payload = merge_dict(payload, self.data["pattern"])
    return json.dumps(payload)


# Traceback (KeyError)
2020-09-17 09:37:55,669: custodian.policy:INFO Provisioning policy lambda: health-event-notify region: us-east-1
2020-09-17 09:37:55,924: custodian.output:ERROR Error while executing policy
Traceback (most recent call last):
File "/home/kapilt/projects/cloud-custodian/c7n/policy.py", line 508, in provision
return manager.publish(
File "/home/kapilt/projects/cloud-custodian/c7n/mu.py", line 397, in publish
if e.add(func):
File "/home/kapilt/projects/cloud-custodian/c7n/mu.py", line 1104, in add
pattern = self.render_event_pattern()
File "/home/kapilt/projects/cloud-custodian/c7n/mu.py", line 1080, in render_event_pattern
payload['detail']['eventTypeCategory'] = self.data['categories']
KeyError: 'detail'

# Fixed code
def render_event_pattern(self):
    event_type = self.data.get("type")
    pattern = self.data.get("pattern")

    payload = {}
    if pattern:
        payload.update(pattern)

    if event_type == "cloudtrail":
        payload["detail-type"] = ["AWS API Call via CloudTrail"]
        self.resolve_cloudtrail_payload(payload)
    if event_type == "cloudtrail":
        if "signin.amazonaws.com" in payload["detail"]["eventSource"]:
            payload["detail-type"] = ["AWS Console Sign In via CloudTrail"]
    elif event_type == "guard-duty":
        payload["source"] = ["aws.guardduty"]
        payload["detail-type"] = ["GuardDuty Finding"]
        if "resource-filter" in self.data:
            payload.update(
                {
                    "detail": {
                        "resource": {"resourceType": [self.data["resource-filter"]]}
                    }
                }
            )
    elif event_type == "ec2-instance-state":
        payload["source"] = ["aws.ec2"]
        payload["detail-type"] = ["EC2 Instance State-change Notification"]
        # Technically could let empty be all events, but likely misconfig
        payload["detail"] = {"state": self.data.get("events", [])}
    elif event_type == "asg-instance-state":
        payload["source"] = ["aws.autoscaling"]
        events = []
        for e in self.data.get("events", []):
            events.append(self.ASG_EVENT_MAPPING.get(e, e))
        payload["detail-type"] = events
    elif event_type == "phd":
        payload["source"] = ["aws.health"]
        payload.setdefault("detail", {})
        if self.data.get("events"):
            payload["detail"].update({"eventTypeCode": list(self.data["events"])})
        if self.data.get("categories", []):
            payload["detail"]["eventTypeCategory"] = self.data["categories"]
    elif event_type == "hub-finding":
        payload["source"] = ["aws.securityhub"]
        payload["detail-type"] = ["Security Hub Findings - Imported"]
    elif event_type == "hub-action":
        payload["source"] = ["aws.securityhub"]
        payload["detail-type"] = [
            "Security Hub Findings - Custom Action",
            "Security Hub Insight Results",
        ]
    elif event_type == "periodic":
        pass
    else:
        raise ValueError("Unknown lambda event source type: %s" % event_type)
    if not payload:
        return None
    if self.data.get("pattern"):
        payload = merge_dict(payload, self.data["pattern"])
    return json.dumps(payload)