We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Remove or edit unreachable code block
@minrk It looks like `_check_user_model` has a few code lines that don't seem to be reachable. Should we remove the lines after the return statement? https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/apihandlers/base.py#L144


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `jupyterhub/apihandlers/base.py`
Content:
```
1 """Base API handlers"""
2 # Copyright (c) Jupyter Development Team.
3 # Distributed under the terms of the Modified BSD License.
4 
5 import json
6 
7 from http.client import responses
8 
9 from tornado import web
10 
11 from ..handlers import BaseHandler
12 from ..utils import url_path_join
13 
14 class APIHandler(BaseHandler):
15 
16     def check_referer(self):
17         """Check Origin for cross-site API requests.
18         
19         Copied from WebSocket with changes:
20         
21         - allow unspecified host/referer (e.g. scripts)
22         """
23         host = self.request.headers.get("Host")
24         referer = self.request.headers.get("Referer")
25 
26         # If no header is provided, assume it comes from a script/curl.
27         # We are only concerned with cross-site browser stuff here.
28         if not host:
29             self.log.warning("Blocking API request with no host")
30             return False
31         if not referer:
32             self.log.warning("Blocking API request with no referer")
33             return False
34         
35         host_path = url_path_join(host, self.hub.server.base_url)
36         referer_path = referer.split('://', 1)[-1]
37         if not (referer_path + '/').startswith(host_path):
38             self.log.warning("Blocking Cross Origin API request.  Referer: %s, Host: %s",
39                 referer, host_path)
40             return False
41         return True
42     
43     def get_current_user_cookie(self):
44         """Override get_user_cookie to check Referer header"""
45         cookie_user = super().get_current_user_cookie()
46         # check referer only if there is a cookie user,
47         # avoiding misleading "Blocking Cross Origin" messages
48         # when there's no cookie set anyway.
49         if cookie_user and not self.check_referer():
50             return None
51         return cookie_user
52 
53     def get_json_body(self):
54         """Return the body of the request as JSON data."""
55         if not self.request.body:
56             return None
57         body = self.request.body.strip().decode('utf-8')
58         try:
59             model = json.loads(body)
60         except Exception:
61             self.log.debug("Bad JSON: %r", body)
62             self.log.error("Couldn't parse JSON", exc_info=True)
63             raise web.HTTPError(400, 'Invalid JSON in body of request')
64         return model
65     
66     def write_error(self, status_code, **kwargs):
67         """Write JSON errors instead of HTML"""
68         exc_info = kwargs.get('exc_info')
69         message = ''
70         status_message = responses.get(status_code, 'Unknown Error')
71         if exc_info:
72             exception = exc_info[1]
73             # get the custom message, if defined
74             try:
75                 message = exception.log_message % exception.args
76             except Exception:
77                 pass
78 
79             # construct the custom reason, if defined
80             reason = getattr(exception, 'reason', '')
81             if reason:
82                 status_message = reason
83         self.set_header('Content-Type', 'application/json')
84         self.write(json.dumps({
85             'status': status_code,
86             'message': message or status_message,
87         }))
88 
89     def user_model(self, user):
90         """Get the JSON model for a User object"""
91         model = {
92             'name': user.name,
93             'admin': user.admin,
94             'groups': [ g.name for g in user.groups ],
95             'server': user.url if user.running else None,
96             'pending': None,
97             'last_activity': user.last_activity.isoformat(),
98         }
99         if user.spawn_pending:
100             model['pending'] = 'spawn'
101         elif user.stop_pending:
102             model['pending'] = 'stop'
103         return model
104 
105     def group_model(self, group):
106         """Get the JSON model for a Group object"""
107         return {
108             'name': group.name,
109             'users': [ u.name for u in group.users ]
110         }
111 
112     _user_model_types = {
113         'name': str,
114         'admin': bool,
115         'groups': list,
116     }
117 
118     _group_model_types = {
119         'name': str,
120         'users': list,
121     }
122 
123     def _check_model(self, model, model_types, name):
124         """Check a model provided by a REST API request
125         
126         Args:
127             model (dict): user-provided model
128             model_types (dict): dict of key:type used to validate types and keys
129             name (str): name of the model, used in error messages
130         """
131         if not isinstance(model, dict):
132             raise web.HTTPError(400, "Invalid JSON data: %r" % model)
133         if not set(model).issubset(set(model_types)):
134             raise web.HTTPError(400, "Invalid JSON keys: %r" % model)
135         for key, value in model.items():
136             if not isinstance(value, model_types[key]):
137                 raise web.HTTPError(400, "%s.%s must be %s, not: %r" % (
138                     name, key, model_types[key], type(value)
139                 ))
140 
141     def _check_user_model(self, model):
142         """Check a request-provided user model from a REST API"""
143         return self._check_model(model, self._user_model_types, 'user')
144         for groupname in model.get('groups', []):
145             if not isinstance(groupname, str):
146                 raise web.HTTPError(400, "group names must be str, not %r" % type(groupname))
147 
148     def _check_group_model(self, model):
149         """Check a request-provided user model from a REST API"""
150         self._check_model(model, self._group_model_types, 'group')
151         for username in model.get('users', []):
152             if not isinstance(username, str):
153                 raise web.HTTPError(400, "usernames must be str, not %r" % type(groupname))
154 
155     def options(self, *args, **kwargs):
156         self.set_header('Access-Control-Allow-Headers', 'accept, content-type')
157         self.finish()
158
```
--- 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/jupyterhub/apihandlers/base.py b/jupyterhub/apihandlers/base.py
--- a/jupyterhub/apihandlers/base.py
+++ b/jupyterhub/apihandlers/base.py
@@ -140,19 +140,18 @@
 
     def _check_user_model(self, model):
         """Check a request-provided user model from a REST API"""
-        return self._check_model(model, self._user_model_types, 'user')
-        for groupname in model.get('groups', []):
-            if not isinstance(groupname, str):
-                raise web.HTTPError(400, "group names must be str, not %r" % type(groupname))
+        self._check_model(model, self._user_model_types, 'user')
+        for username in model.get('users', []):
+            if not isinstance(username, str):
+                raise web.HTTPError(400, ("usernames must be str, not %r", type(username)))
 
     def _check_group_model(self, model):
-        """Check a request-provided user model from a REST API"""
+        """Check a request-provided group model from a REST API"""
         self._check_model(model, self._group_model_types, 'group')
-        for username in model.get('users', []):
-            if not isinstance(username, str):
-                raise web.HTTPError(400, "usernames must be str, not %r" % type(groupname))
+        for groupname in model.get('groups', []):
+            if not isinstance(groupname, str):
+                raise web.HTTPError(400, ("group names must be str, not %r", type(groupname)))
 
     def options(self, *args, **kwargs):
         self.set_header('Access-Control-Allow-Headers', 'accept, content-type')
         self.finish()
-    
\ No newline at end of file

{"golden_diff": "diff --git a/jupyterhub/apihandlers/base.py b/jupyterhub/apihandlers/base.py\n--- a/jupyterhub/apihandlers/base.py\n+++ b/jupyterhub/apihandlers/base.py\n@@ -140,19 +140,18 @@\n \n     def _check_user_model(self, model):\n         \"\"\"Check a request-provided user model from a REST API\"\"\"\n-        return self._check_model(model, self._user_model_types, 'user')\n-        for groupname in model.get('groups', []):\n-            if not isinstance(groupname, str):\n-                raise web.HTTPError(400, \"group names must be str, not %r\" % type(groupname))\n+        self._check_model(model, self._user_model_types, 'user')\n+        for username in model.get('users', []):\n+            if not isinstance(username, str):\n+                raise web.HTTPError(400, (\"usernames must be str, not %r\", type(username)))\n \n     def _check_group_model(self, model):\n-        \"\"\"Check a request-provided user model from a REST API\"\"\"\n+        \"\"\"Check a request-provided group model from a REST API\"\"\"\n         self._check_model(model, self._group_model_types, 'group')\n-        for username in model.get('users', []):\n-            if not isinstance(username, str):\n-                raise web.HTTPError(400, \"usernames must be str, not %r\" % type(groupname))\n+        for groupname in model.get('groups', []):\n+            if not isinstance(groupname, str):\n+                raise web.HTTPError(400, (\"group names must be str, not %r\", type(groupname)))\n \n     def options(self, *args, **kwargs):\n         self.set_header('Access-Control-Allow-Headers', 'accept, content-type')\n         self.finish()\n-    \n\\ No newline at end of file\n", "issue": "Remove or edit unreachable code block\n@minrk It looks like `_check_user_model` has a few code lines that don't seem to be reachable. Should we remove the lines after the return statement? https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/apihandlers/base.py#L144\n\n", "before_files": [{"content": "\"\"\"Base API handlers\"\"\"\n# Copyright (c) Jupyter Development Team.\n# Distributed under the terms of the Modified BSD License.\n\nimport json\n\nfrom http.client import responses\n\nfrom tornado import web\n\nfrom ..handlers import BaseHandler\nfrom ..utils import url_path_join\n\nclass APIHandler(BaseHandler):\n\n    def check_referer(self):\n        \"\"\"Check Origin for cross-site API requests.\n        \n        Copied from WebSocket with changes:\n        \n        - allow unspecified host/referer (e.g. scripts)\n        \"\"\"\n        host = self.request.headers.get(\"Host\")\n        referer = self.request.headers.get(\"Referer\")\n\n        # If no header is provided, assume it comes from a script/curl.\n        # We are only concerned with cross-site browser stuff here.\n        if not host:\n            self.log.warning(\"Blocking API request with no host\")\n            return False\n        if not referer:\n            self.log.warning(\"Blocking API request with no referer\")\n            return False\n        \n        host_path = url_path_join(host, self.hub.server.base_url)\n        referer_path = referer.split('://', 1)[-1]\n        if not (referer_path + '/').startswith(host_path):\n            self.log.warning(\"Blocking Cross Origin API request.  Referer: %s, Host: %s\",\n                referer, host_path)\n            return False\n        return True\n    \n    def get_current_user_cookie(self):\n        \"\"\"Override get_user_cookie to check Referer header\"\"\"\n        cookie_user = super().get_current_user_cookie()\n        # check referer only if there is a cookie user,\n        # avoiding misleading \"Blocking Cross Origin\" messages\n        # when there's no cookie set anyway.\n        if cookie_user and not self.check_referer():\n            return None\n        return cookie_user\n\n    def get_json_body(self):\n        \"\"\"Return the body of the request as JSON data.\"\"\"\n        if not self.request.body:\n            return None\n        body = self.request.body.strip().decode('utf-8')\n        try:\n            model = json.loads(body)\n        except Exception:\n            self.log.debug(\"Bad JSON: %r\", body)\n            self.log.error(\"Couldn't parse JSON\", exc_info=True)\n            raise web.HTTPError(400, 'Invalid JSON in body of request')\n        return model\n    \n    def write_error(self, status_code, **kwargs):\n        \"\"\"Write JSON errors instead of HTML\"\"\"\n        exc_info = kwargs.get('exc_info')\n        message = ''\n        status_message = responses.get(status_code, 'Unknown Error')\n        if exc_info:\n            exception = exc_info[1]\n            # get the custom message, if defined\n            try:\n                message = exception.log_message % exception.args\n            except Exception:\n                pass\n\n            # construct the custom reason, if defined\n            reason = getattr(exception, 'reason', '')\n            if reason:\n                status_message = reason\n        self.set_header('Content-Type', 'application/json')\n        self.write(json.dumps({\n            'status': status_code,\n            'message': message or status_message,\n        }))\n\n    def user_model(self, user):\n        \"\"\"Get the JSON model for a User object\"\"\"\n        model = {\n            'name': user.name,\n            'admin': user.admin,\n            'groups': [ g.name for g in user.groups ],\n            'server': user.url if user.running else None,\n            'pending': None,\n            'last_activity': user.last_activity.isoformat(),\n        }\n        if user.spawn_pending:\n            model['pending'] = 'spawn'\n        elif user.stop_pending:\n            model['pending'] = 'stop'\n        return model\n\n    def group_model(self, group):\n        \"\"\"Get the JSON model for a Group object\"\"\"\n        return {\n            'name': group.name,\n            'users': [ u.name for u in group.users ]\n        }\n\n    _user_model_types = {\n        'name': str,\n        'admin': bool,\n        'groups': list,\n    }\n\n    _group_model_types = {\n        'name': str,\n        'users': list,\n    }\n\n    def _check_model(self, model, model_types, name):\n        \"\"\"Check a model provided by a REST API request\n        \n        Args:\n            model (dict): user-provided model\n            model_types (dict): dict of key:type used to validate types and keys\n            name (str): name of the model, used in error messages\n        \"\"\"\n        if not isinstance(model, dict):\n            raise web.HTTPError(400, \"Invalid JSON data: %r\" % model)\n        if not set(model).issubset(set(model_types)):\n            raise web.HTTPError(400, \"Invalid JSON keys: %r\" % model)\n        for key, value in model.items():\n            if not isinstance(value, model_types[key]):\n                raise web.HTTPError(400, \"%s.%s must be %s, not: %r\" % (\n                    name, key, model_types[key], type(value)\n                ))\n\n    def _check_user_model(self, model):\n        \"\"\"Check a request-provided user model from a REST API\"\"\"\n        return self._check_model(model, self._user_model_types, 'user')\n        for groupname in model.get('groups', []):\n            if not isinstance(groupname, str):\n                raise web.HTTPError(400, \"group names must be str, not %r\" % type(groupname))\n\n    def _check_group_model(self, model):\n        \"\"\"Check a request-provided user model from a REST API\"\"\"\n        self._check_model(model, self._group_model_types, 'group')\n        for username in model.get('users', []):\n            if not isinstance(username, str):\n                raise web.HTTPError(400, \"usernames must be str, not %r\" % type(groupname))\n\n    def options(self, *args, **kwargs):\n        self.set_header('Access-Control-Allow-Headers', 'accept, content-type')\n        self.finish()\n    ", "path": "jupyterhub/apihandlers/base.py"}], "after_files": [{"content": "\"\"\"Base API handlers\"\"\"\n# Copyright (c) Jupyter Development Team.\n# Distributed under the terms of the Modified BSD License.\n\nimport json\n\nfrom http.client import responses\n\nfrom tornado import web\n\nfrom ..handlers import BaseHandler\nfrom ..utils import url_path_join\n\nclass APIHandler(BaseHandler):\n\n    def check_referer(self):\n        \"\"\"Check Origin for cross-site API requests.\n        \n        Copied from WebSocket with changes:\n        \n        - allow unspecified host/referer (e.g. scripts)\n        \"\"\"\n        host = self.request.headers.get(\"Host\")\n        referer = self.request.headers.get(\"Referer\")\n\n        # If no header is provided, assume it comes from a script/curl.\n        # We are only concerned with cross-site browser stuff here.\n        if not host:\n            self.log.warning(\"Blocking API request with no host\")\n            return False\n        if not referer:\n            self.log.warning(\"Blocking API request with no referer\")\n            return False\n        \n        host_path = url_path_join(host, self.hub.server.base_url)\n        referer_path = referer.split('://', 1)[-1]\n        if not (referer_path + '/').startswith(host_path):\n            self.log.warning(\"Blocking Cross Origin API request.  Referer: %s, Host: %s\",\n                referer, host_path)\n            return False\n        return True\n    \n    def get_current_user_cookie(self):\n        \"\"\"Override get_user_cookie to check Referer header\"\"\"\n        cookie_user = super().get_current_user_cookie()\n        # check referer only if there is a cookie user,\n        # avoiding misleading \"Blocking Cross Origin\" messages\n        # when there's no cookie set anyway.\n        if cookie_user and not self.check_referer():\n            return None\n        return cookie_user\n\n    def get_json_body(self):\n        \"\"\"Return the body of the request as JSON data.\"\"\"\n        if not self.request.body:\n            return None\n        body = self.request.body.strip().decode('utf-8')\n        try:\n            model = json.loads(body)\n        except Exception:\n            self.log.debug(\"Bad JSON: %r\", body)\n            self.log.error(\"Couldn't parse JSON\", exc_info=True)\n            raise web.HTTPError(400, 'Invalid JSON in body of request')\n        return model\n    \n    def write_error(self, status_code, **kwargs):\n        \"\"\"Write JSON errors instead of HTML\"\"\"\n        exc_info = kwargs.get('exc_info')\n        message = ''\n        status_message = responses.get(status_code, 'Unknown Error')\n        if exc_info:\n            exception = exc_info[1]\n            # get the custom message, if defined\n            try:\n                message = exception.log_message % exception.args\n            except Exception:\n                pass\n\n            # construct the custom reason, if defined\n            reason = getattr(exception, 'reason', '')\n            if reason:\n                status_message = reason\n        self.set_header('Content-Type', 'application/json')\n        self.write(json.dumps({\n            'status': status_code,\n            'message': message or status_message,\n        }))\n\n    def user_model(self, user):\n        \"\"\"Get the JSON model for a User object\"\"\"\n        model = {\n            'name': user.name,\n            'admin': user.admin,\n            'groups': [ g.name for g in user.groups ],\n            'server': user.url if user.running else None,\n            'pending': None,\n            'last_activity': user.last_activity.isoformat(),\n        }\n        if user.spawn_pending:\n            model['pending'] = 'spawn'\n        elif user.stop_pending:\n            model['pending'] = 'stop'\n        return model\n\n    def group_model(self, group):\n        \"\"\"Get the JSON model for a Group object\"\"\"\n        return {\n            'name': group.name,\n            'users': [ u.name for u in group.users ]\n        }\n\n    _user_model_types = {\n        'name': str,\n        'admin': bool,\n        'groups': list,\n    }\n\n    _group_model_types = {\n        'name': str,\n        'users': list,\n    }\n\n    def _check_model(self, model, model_types, name):\n        \"\"\"Check a model provided by a REST API request\n        \n        Args:\n            model (dict): user-provided model\n            model_types (dict): dict of key:type used to validate types and keys\n            name (str): name of the model, used in error messages\n        \"\"\"\n        if not isinstance(model, dict):\n            raise web.HTTPError(400, \"Invalid JSON data: %r\" % model)\n        if not set(model).issubset(set(model_types)):\n            raise web.HTTPError(400, \"Invalid JSON keys: %r\" % model)\n        for key, value in model.items():\n            if not isinstance(value, model_types[key]):\n                raise web.HTTPError(400, \"%s.%s must be %s, not: %r\" % (\n                    name, key, model_types[key], type(value)\n                ))\n\n    def _check_user_model(self, model):\n        \"\"\"Check a request-provided user model from a REST API\"\"\"\n        self._check_model(model, self._user_model_types, 'user')\n        for username in model.get('users', []):\n            if not isinstance(username, str):\n                raise web.HTTPError(400, (\"usernames must be str, not %r\", type(username)))\n\n    def _check_group_model(self, model):\n        \"\"\"Check a request-provided group model from a REST API\"\"\"\n        self._check_model(model, self._group_model_types, 'group')\n        for groupname in model.get('groups', []):\n            if not isinstance(groupname, str):\n                raise web.HTTPError(400, (\"group names must be str, not %r\", type(groupname)))\n\n    def options(self, *args, **kwargs):\n        self.set_header('Access-Control-Allow-Headers', 'accept, content-type')\n        self.finish()\n", "path": "jupyterhub/apihandlers/base.py"}]}