We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
KeyError: 'expiry_template_html'
```
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/rav/work/synapse/synapse/app/homeserver.py", line 661, in <module>
    main()
  File "/home/rav/work/synapse/synapse/app/homeserver.py", line 656, in main
    hs = setup(sys.argv[1:])
  File "/home/rav/work/synapse/synapse/app/homeserver.py", line 329, in setup
    config_options,
  File "/home/rav/work/synapse/synapse/config/_base.py", line 362, in load_or_generate_config
    generate_keys=generate_keys,
  File "/home/rav/work/synapse/synapse/config/_base.py", line 408, in read_config_files
    self.parse_config_dict(config)
  File "/home/rav/work/synapse/synapse/config/_base.py", line 411, in parse_config_dict
    self.invoke_all("read_config", config_dict)
  File "/home/rav/work/synapse/synapse/config/_base.py", line 146, in invoke_all
    results.append(getattr(cls, name)(self, *args, **kargs))
  File "/home/rav/work/synapse/synapse/config/emailconfig.py", line 74, in read_config
    self.email_expiry_template_html = email_config["expiry_template_html"]
KeyError: 'expiry_template_html'
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `synapse/config/emailconfig.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # Copyright 2015, 2016 OpenMarket Ltd
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from __future__ import print_function
17 
18 # This file can't be called email.py because if it is, we cannot:
19 import email.utils
20 import logging
21 import os
22 
23 import pkg_resources
24 
25 from ._base import Config, ConfigError
26 
27 logger = logging.getLogger(__name__)
28 
29 
30 class EmailConfig(Config):
31     def read_config(self, config):
32         self.email_enable_notifs = False
33 
34         email_config = config.get("email", {})
35         self.email_enable_notifs = email_config.get("enable_notifs", False)
36 
37         if self.email_enable_notifs:
38             # make sure we can import the required deps
39             import jinja2
40             import bleach
41             # prevent unused warnings
42             jinja2
43             bleach
44 
45             required = [
46                 "smtp_host",
47                 "smtp_port",
48                 "notif_from",
49                 "notif_template_html",
50                 "notif_template_text",
51             ]
52 
53             missing = []
54             for k in required:
55                 if k not in email_config:
56                     missing.append(k)
57 
58             if (len(missing) > 0):
59                 raise RuntimeError(
60                     "email.enable_notifs is True but required keys are missing: %s" %
61                     (", ".join(["email." + k for k in missing]),)
62                 )
63 
64             if config.get("public_baseurl") is None:
65                 raise RuntimeError(
66                     "email.enable_notifs is True but no public_baseurl is set"
67                 )
68 
69             self.email_smtp_host = email_config["smtp_host"]
70             self.email_smtp_port = email_config["smtp_port"]
71             self.email_notif_from = email_config["notif_from"]
72             self.email_notif_template_html = email_config["notif_template_html"]
73             self.email_notif_template_text = email_config["notif_template_text"]
74             self.email_expiry_template_html = email_config["expiry_template_html"]
75             self.email_expiry_template_text = email_config["expiry_template_text"]
76 
77             template_dir = email_config.get("template_dir")
78             # we need an absolute path, because we change directory after starting (and
79             # we don't yet know what auxilliary templates like mail.css we will need).
80             # (Note that loading as package_resources with jinja.PackageLoader doesn't
81             # work for the same reason.)
82             if not template_dir:
83                 template_dir = pkg_resources.resource_filename(
84                     'synapse', 'res/templates'
85                 )
86             template_dir = os.path.abspath(template_dir)
87 
88             for f in self.email_notif_template_text, self.email_notif_template_html:
89                 p = os.path.join(template_dir, f)
90                 if not os.path.isfile(p):
91                     raise ConfigError("Unable to find email template file %s" % (p, ))
92             self.email_template_dir = template_dir
93 
94             self.email_notif_for_new_users = email_config.get(
95                 "notif_for_new_users", True
96             )
97             self.email_riot_base_url = email_config.get(
98                 "riot_base_url", None
99             )
100             self.email_smtp_user = email_config.get(
101                 "smtp_user", None
102             )
103             self.email_smtp_pass = email_config.get(
104                 "smtp_pass", None
105             )
106             self.require_transport_security = email_config.get(
107                 "require_transport_security", False
108             )
109             if "app_name" in email_config:
110                 self.email_app_name = email_config["app_name"]
111             else:
112                 self.email_app_name = "Matrix"
113 
114             # make sure it's valid
115             parsed = email.utils.parseaddr(self.email_notif_from)
116             if parsed[1] == '':
117                 raise RuntimeError("Invalid notif_from address")
118         else:
119             self.email_enable_notifs = False
120             # Not much point setting defaults for the rest: it would be an
121             # error for them to be used.
122 
123     def default_config(self, config_dir_path, server_name, **kwargs):
124         return """
125         # Enable sending emails for notification events or expiry notices
126         # Defining a custom URL for Riot is only needed if email notifications
127         # should contain links to a self-hosted installation of Riot; when set
128         # the "app_name" setting is ignored.
129         #
130         # If your SMTP server requires authentication, the optional smtp_user &
131         # smtp_pass variables should be used
132         #
133         #email:
134         #   enable_notifs: false
135         #   smtp_host: "localhost"
136         #   smtp_port: 25
137         #   smtp_user: "exampleusername"
138         #   smtp_pass: "examplepassword"
139         #   require_transport_security: False
140         #   notif_from: "Your Friendly %(app)s Home Server <noreply@example.com>"
141         #   app_name: Matrix
142         #   # if template_dir is unset, uses the example templates that are part of
143         #   # the Synapse distribution.
144         #   #template_dir: res/templates
145         #   notif_template_html: notif_mail.html
146         #   notif_template_text: notif_mail.txt
147         #   # Templates for account expiry notices.
148         #   expiry_template_html: notice_expiry.html
149         #   expiry_template_text: notice_expiry.txt
150         #   notif_for_new_users: True
151         #   riot_base_url: "http://localhost/riot"
152         """
153
```
--- 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/synapse/config/emailconfig.py b/synapse/config/emailconfig.py
--- a/synapse/config/emailconfig.py
+++ b/synapse/config/emailconfig.py
@@ -71,8 +71,12 @@
             self.email_notif_from = email_config["notif_from"]
             self.email_notif_template_html = email_config["notif_template_html"]
             self.email_notif_template_text = email_config["notif_template_text"]
-            self.email_expiry_template_html = email_config["expiry_template_html"]
-            self.email_expiry_template_text = email_config["expiry_template_text"]
+            self.email_expiry_template_html = email_config.get(
+                "expiry_template_html", "notice_expiry.html",
+            )
+            self.email_expiry_template_text = email_config.get(
+                "expiry_template_text", "notice_expiry.txt",
+            )
 
             template_dir = email_config.get("template_dir")
             # we need an absolute path, because we change directory after starting (and

{"golden_diff": "diff --git a/synapse/config/emailconfig.py b/synapse/config/emailconfig.py\n--- a/synapse/config/emailconfig.py\n+++ b/synapse/config/emailconfig.py\n@@ -71,8 +71,12 @@\n             self.email_notif_from = email_config[\"notif_from\"]\n             self.email_notif_template_html = email_config[\"notif_template_html\"]\n             self.email_notif_template_text = email_config[\"notif_template_text\"]\n-            self.email_expiry_template_html = email_config[\"expiry_template_html\"]\n-            self.email_expiry_template_text = email_config[\"expiry_template_text\"]\n+            self.email_expiry_template_html = email_config.get(\n+                \"expiry_template_html\", \"notice_expiry.html\",\n+            )\n+            self.email_expiry_template_text = email_config.get(\n+                \"expiry_template_text\", \"notice_expiry.txt\",\n+            )\n \n             template_dir = email_config.get(\"template_dir\")\n             # we need an absolute path, because we change directory after starting (and\n", "issue": "KeyError: 'expiry_template_html'\n```\r\nTraceback (most recent call last):\r\n  File \"/usr/lib/python3.6/runpy.py\", line 193, in _run_module_as_main\r\n    \"__main__\", mod_spec)\r\n  File \"/usr/lib/python3.6/runpy.py\", line 85, in _run_code\r\n    exec(code, run_globals)\r\n  File \"/home/rav/work/synapse/synapse/app/homeserver.py\", line 661, in <module>\r\n    main()\r\n  File \"/home/rav/work/synapse/synapse/app/homeserver.py\", line 656, in main\r\n    hs = setup(sys.argv[1:])\r\n  File \"/home/rav/work/synapse/synapse/app/homeserver.py\", line 329, in setup\r\n    config_options,\r\n  File \"/home/rav/work/synapse/synapse/config/_base.py\", line 362, in load_or_generate_config\r\n    generate_keys=generate_keys,\r\n  File \"/home/rav/work/synapse/synapse/config/_base.py\", line 408, in read_config_files\r\n    self.parse_config_dict(config)\r\n  File \"/home/rav/work/synapse/synapse/config/_base.py\", line 411, in parse_config_dict\r\n    self.invoke_all(\"read_config\", config_dict)\r\n  File \"/home/rav/work/synapse/synapse/config/_base.py\", line 146, in invoke_all\r\n    results.append(getattr(cls, name)(self, *args, **kargs))\r\n  File \"/home/rav/work/synapse/synapse/config/emailconfig.py\", line 74, in read_config\r\n    self.email_expiry_template_html = email_config[\"expiry_template_html\"]\r\nKeyError: 'expiry_template_html'\r\n```\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright 2015, 2016 OpenMarket Ltd\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import print_function\n\n# This file can't be called email.py because if it is, we cannot:\nimport email.utils\nimport logging\nimport os\n\nimport pkg_resources\n\nfrom ._base import Config, ConfigError\n\nlogger = logging.getLogger(__name__)\n\n\nclass EmailConfig(Config):\n    def read_config(self, config):\n        self.email_enable_notifs = False\n\n        email_config = config.get(\"email\", {})\n        self.email_enable_notifs = email_config.get(\"enable_notifs\", False)\n\n        if self.email_enable_notifs:\n            # make sure we can import the required deps\n            import jinja2\n            import bleach\n            # prevent unused warnings\n            jinja2\n            bleach\n\n            required = [\n                \"smtp_host\",\n                \"smtp_port\",\n                \"notif_from\",\n                \"notif_template_html\",\n                \"notif_template_text\",\n            ]\n\n            missing = []\n            for k in required:\n                if k not in email_config:\n                    missing.append(k)\n\n            if (len(missing) > 0):\n                raise RuntimeError(\n                    \"email.enable_notifs is True but required keys are missing: %s\" %\n                    (\", \".join([\"email.\" + k for k in missing]),)\n                )\n\n            if config.get(\"public_baseurl\") is None:\n                raise RuntimeError(\n                    \"email.enable_notifs is True but no public_baseurl is set\"\n                )\n\n            self.email_smtp_host = email_config[\"smtp_host\"]\n            self.email_smtp_port = email_config[\"smtp_port\"]\n            self.email_notif_from = email_config[\"notif_from\"]\n            self.email_notif_template_html = email_config[\"notif_template_html\"]\n            self.email_notif_template_text = email_config[\"notif_template_text\"]\n            self.email_expiry_template_html = email_config[\"expiry_template_html\"]\n            self.email_expiry_template_text = email_config[\"expiry_template_text\"]\n\n            template_dir = email_config.get(\"template_dir\")\n            # we need an absolute path, because we change directory after starting (and\n            # we don't yet know what auxilliary templates like mail.css we will need).\n            # (Note that loading as package_resources with jinja.PackageLoader doesn't\n            # work for the same reason.)\n            if not template_dir:\n                template_dir = pkg_resources.resource_filename(\n                    'synapse', 'res/templates'\n                )\n            template_dir = os.path.abspath(template_dir)\n\n            for f in self.email_notif_template_text, self.email_notif_template_html:\n                p = os.path.join(template_dir, f)\n                if not os.path.isfile(p):\n                    raise ConfigError(\"Unable to find email template file %s\" % (p, ))\n            self.email_template_dir = template_dir\n\n            self.email_notif_for_new_users = email_config.get(\n                \"notif_for_new_users\", True\n            )\n            self.email_riot_base_url = email_config.get(\n                \"riot_base_url\", None\n            )\n            self.email_smtp_user = email_config.get(\n                \"smtp_user\", None\n            )\n            self.email_smtp_pass = email_config.get(\n                \"smtp_pass\", None\n            )\n            self.require_transport_security = email_config.get(\n                \"require_transport_security\", False\n            )\n            if \"app_name\" in email_config:\n                self.email_app_name = email_config[\"app_name\"]\n            else:\n                self.email_app_name = \"Matrix\"\n\n            # make sure it's valid\n            parsed = email.utils.parseaddr(self.email_notif_from)\n            if parsed[1] == '':\n                raise RuntimeError(\"Invalid notif_from address\")\n        else:\n            self.email_enable_notifs = False\n            # Not much point setting defaults for the rest: it would be an\n            # error for them to be used.\n\n    def default_config(self, config_dir_path, server_name, **kwargs):\n        return \"\"\"\n        # Enable sending emails for notification events or expiry notices\n        # Defining a custom URL for Riot is only needed if email notifications\n        # should contain links to a self-hosted installation of Riot; when set\n        # the \"app_name\" setting is ignored.\n        #\n        # If your SMTP server requires authentication, the optional smtp_user &\n        # smtp_pass variables should be used\n        #\n        #email:\n        #   enable_notifs: false\n        #   smtp_host: \"localhost\"\n        #   smtp_port: 25\n        #   smtp_user: \"exampleusername\"\n        #   smtp_pass: \"examplepassword\"\n        #   require_transport_security: False\n        #   notif_from: \"Your Friendly %(app)s Home Server <noreply@example.com>\"\n        #   app_name: Matrix\n        #   # if template_dir is unset, uses the example templates that are part of\n        #   # the Synapse distribution.\n        #   #template_dir: res/templates\n        #   notif_template_html: notif_mail.html\n        #   notif_template_text: notif_mail.txt\n        #   # Templates for account expiry notices.\n        #   expiry_template_html: notice_expiry.html\n        #   expiry_template_text: notice_expiry.txt\n        #   notif_for_new_users: True\n        #   riot_base_url: \"http://localhost/riot\"\n        \"\"\"\n", "path": "synapse/config/emailconfig.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright 2015, 2016 OpenMarket Ltd\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import print_function\n\n# This file can't be called email.py because if it is, we cannot:\nimport email.utils\nimport logging\nimport os\n\nimport pkg_resources\n\nfrom ._base import Config, ConfigError\n\nlogger = logging.getLogger(__name__)\n\n\nclass EmailConfig(Config):\n    def read_config(self, config):\n        self.email_enable_notifs = False\n\n        email_config = config.get(\"email\", {})\n        self.email_enable_notifs = email_config.get(\"enable_notifs\", False)\n\n        if self.email_enable_notifs:\n            # make sure we can import the required deps\n            import jinja2\n            import bleach\n            # prevent unused warnings\n            jinja2\n            bleach\n\n            required = [\n                \"smtp_host\",\n                \"smtp_port\",\n                \"notif_from\",\n                \"notif_template_html\",\n                \"notif_template_text\",\n            ]\n\n            missing = []\n            for k in required:\n                if k not in email_config:\n                    missing.append(k)\n\n            if (len(missing) > 0):\n                raise RuntimeError(\n                    \"email.enable_notifs is True but required keys are missing: %s\" %\n                    (\", \".join([\"email.\" + k for k in missing]),)\n                )\n\n            if config.get(\"public_baseurl\") is None:\n                raise RuntimeError(\n                    \"email.enable_notifs is True but no public_baseurl is set\"\n                )\n\n            self.email_smtp_host = email_config[\"smtp_host\"]\n            self.email_smtp_port = email_config[\"smtp_port\"]\n            self.email_notif_from = email_config[\"notif_from\"]\n            self.email_notif_template_html = email_config[\"notif_template_html\"]\n            self.email_notif_template_text = email_config[\"notif_template_text\"]\n            self.email_expiry_template_html = email_config.get(\n                \"expiry_template_html\", \"notice_expiry.html\",\n            )\n            self.email_expiry_template_text = email_config.get(\n                \"expiry_template_text\", \"notice_expiry.txt\",\n            )\n\n            template_dir = email_config.get(\"template_dir\")\n            # we need an absolute path, because we change directory after starting (and\n            # we don't yet know what auxilliary templates like mail.css we will need).\n            # (Note that loading as package_resources with jinja.PackageLoader doesn't\n            # work for the same reason.)\n            if not template_dir:\n                template_dir = pkg_resources.resource_filename(\n                    'synapse', 'res/templates'\n                )\n            template_dir = os.path.abspath(template_dir)\n\n            for f in self.email_notif_template_text, self.email_notif_template_html:\n                p = os.path.join(template_dir, f)\n                if not os.path.isfile(p):\n                    raise ConfigError(\"Unable to find email template file %s\" % (p, ))\n            self.email_template_dir = template_dir\n\n            self.email_notif_for_new_users = email_config.get(\n                \"notif_for_new_users\", True\n            )\n            self.email_riot_base_url = email_config.get(\n                \"riot_base_url\", None\n            )\n            self.email_smtp_user = email_config.get(\n                \"smtp_user\", None\n            )\n            self.email_smtp_pass = email_config.get(\n                \"smtp_pass\", None\n            )\n            self.require_transport_security = email_config.get(\n                \"require_transport_security\", False\n            )\n            if \"app_name\" in email_config:\n                self.email_app_name = email_config[\"app_name\"]\n            else:\n                self.email_app_name = \"Matrix\"\n\n            # make sure it's valid\n            parsed = email.utils.parseaddr(self.email_notif_from)\n            if parsed[1] == '':\n                raise RuntimeError(\"Invalid notif_from address\")\n        else:\n            self.email_enable_notifs = False\n            # Not much point setting defaults for the rest: it would be an\n            # error for them to be used.\n\n    def default_config(self, config_dir_path, server_name, **kwargs):\n        return \"\"\"\n        # Enable sending emails for notification events or expiry notices\n        # Defining a custom URL for Riot is only needed if email notifications\n        # should contain links to a self-hosted installation of Riot; when set\n        # the \"app_name\" setting is ignored.\n        #\n        # If your SMTP server requires authentication, the optional smtp_user &\n        # smtp_pass variables should be used\n        #\n        #email:\n        #   enable_notifs: false\n        #   smtp_host: \"localhost\"\n        #   smtp_port: 25\n        #   smtp_user: \"exampleusername\"\n        #   smtp_pass: \"examplepassword\"\n        #   require_transport_security: False\n        #   notif_from: \"Your Friendly %(app)s Home Server <noreply@example.com>\"\n        #   app_name: Matrix\n        #   # if template_dir is unset, uses the example templates that are part of\n        #   # the Synapse distribution.\n        #   #template_dir: res/templates\n        #   notif_template_html: notif_mail.html\n        #   notif_template_text: notif_mail.txt\n        #   # Templates for account expiry notices.\n        #   expiry_template_html: notice_expiry.html\n        #   expiry_template_text: notice_expiry.txt\n        #   notif_for_new_users: True\n        #   riot_base_url: \"http://localhost/riot\"\n        \"\"\"\n", "path": "synapse/config/emailconfig.py"}]}