prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [Contributor Dashboard] Unable to remove question contribution rights in admin dashboard
  We're seeing `InvalidInputException
  Schema validation for 'language_code' failed: Validation failed: is_supported_audio_language_code ({}) for object null` when trying to remove question contribution rights.
  
  <img width="1272" alt="Screen Shot 2021-11-08 at 4 49 25 PM" src="https://user-images.githubusercontent.com/9004726/140823762-9b72375e-4237-4d2f-a2d2-c06af3e375d8.png">
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `core/controllers/payload_validator.py`
  Content:
  ```
  1 # coding: utf-8
  2 
  3 # Copyright 2021 The Oppia Authors. All Rights Reserved.
  4 #
  5 # Licensed under the Apache License, Version 2.0 (the "License");
  6 # you may not use this file except in compliance with the License.
  7 # You may obtain a copy of the License at
  8 #
  9 #      http://www.apache.org/licenses/LICENSE-2.0
  10 #
  11 # Unless required by applicable law or agreed to in writing, software
  12 # distributed under the License is distributed on an "AS-IS" BASIS,
  13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 # See the License for the specific language governing permissions and
  15 # limitations under the License.
  16 
  17 """Validates handler args against its schema by calling schema utils.
  18 Also contains a list of handler class names which does not contain the schema.
  19 """
  20 
  21 from __future__ import annotations
  22 
  23 from core import schema_utils
  24 
  25 from typing import Any, Dict, List, Optional, Tuple, Union
  26 
  27 
  28 # Here Dict[str, Any] is used for arg_schema because the value field of the
  29 # schema is itself a dict that can further contain several nested dicts.
  30 def get_schema_type(arg_schema: Dict[str, Any]) -> str:
  31     """Returns the schema type for an argument.
  32 
  33     Args:
  34         arg_schema: dict(str, *). Schema for an argument.
  35 
  36     Returns:
  37         str. Returns schema type by extracting it from schema.
  38     """
  39     return arg_schema['schema']['type']
  40 
  41 
  42 # Here Dict[str, Any] is used for arg_schema because the value field of the
  43 # schema is itself a dict that can further contain several nested dicts.
  44 def get_corresponding_key_for_object(arg_schema: Dict[str, Any]) -> str:
  45     """Returns the new key for an argument from its schema.
  46 
  47     Args:
  48         arg_schema: dict(str, *). Schema for an argument.
  49 
  50     Returns:
  51         str. The new argument name.
  52     """
  53     return arg_schema['schema']['new_key_for_argument']
  54 
  55 
  56 # This function recursively uses the schema dictionary and handler_args, and
  57 # passes their values to itself as arguments, so their type is Any.
  58 # See: https://github.com/python/mypy/issues/731
  59 def validate_arguments_against_schema(
  60     handler_args: Any,
  61     handler_args_schemas: Any,
  62     allowed_extra_args: bool,
  63     allow_string_to_bool_conversion: bool = False
  64 ) -> Tuple[Dict[str, Any], List[str]]:
  65     """Calls schema utils for normalization of object against its schema
  66     and collects all the errors.
  67 
  68     Args:
  69         handler_args: *. Object for normalization.
  70         handler_args_schemas: dict. Schema for args.
  71         allowed_extra_args: bool. Whether extra args are allowed in handler.
  72         allow_string_to_bool_conversion: bool. Whether to allow string to
  73             boolean coversion.
  74 
  75     Returns:
  76         *. A two tuple, where the first element represents the normalized value
  77         in dict format and the second element represents the lists of errors
  78         after validation.
  79     """
  80     # Collect all errors and present them at once.
  81     errors = []
  82     # Dictionary to hold normalized values of arguments after validation.
  83     normalized_values = {}
  84 
  85     for arg_key, arg_schema in handler_args_schemas.items():
  86 
  87         if arg_key not in handler_args or handler_args[arg_key] is None:
  88             if 'default_value' in arg_schema:
  89                 if arg_schema['default_value'] is None:
  90                     # Skip validation because the argument is optional.
  91                     continue
  92 
  93                 if arg_schema['default_value'] is not None:
  94                     handler_args[arg_key] = arg_schema['default_value']
  95             else:
  96                 errors.append('Missing key in handler args: %s.' % arg_key)
  97                 continue
  98 
  99         # Below normalization is for arguments which are expected to be boolean
  100         # but from API request they are received as string type.
  101         if (
  102                 allow_string_to_bool_conversion and
  103                 get_schema_type(arg_schema) == schema_utils.SCHEMA_TYPE_BOOL
  104                 and isinstance(handler_args[arg_key], str)
  105         ):
  106             handler_args[arg_key] = (
  107                 convert_string_to_bool(handler_args[arg_key]))
  108 
  109         try:
  110             normalized_value = schema_utils.normalize_against_schema(
  111                 handler_args[arg_key], arg_schema['schema'])
  112 
  113             # Modification of argument name if new_key_for_argument
  114             # field is present in the schema.
  115             if 'new_key_for_argument' in arg_schema['schema']:
  116                 arg_key = get_corresponding_key_for_object(arg_schema)
  117             normalized_values[arg_key] = normalized_value
  118         except Exception as e:
  119             errors.append(
  120                 'Schema validation for \'%s\' failed: %s' % (arg_key, e))
  121 
  122     extra_args = set(handler_args.keys()) - set(handler_args_schemas.keys())
  123 
  124     if not allowed_extra_args and extra_args:
  125         errors.append('Found extra args: %s.' % (list(extra_args)))
  126 
  127     return normalized_values, errors
  128 
  129 
  130 def convert_string_to_bool(param: str) -> Optional[Union[bool, str]]:
  131     """Converts a request param of type string into expected bool type.
  132 
  133     Args:
  134         param: str. The params which needs normalization.
  135 
  136     Returns:
  137         bool. Converts the string param into its expected bool type.
  138     """
  139     case_insensitive_param = param.lower()
  140 
  141     if case_insensitive_param == 'true':
  142         return True
  143     elif case_insensitive_param == 'false':
  144         return False
  145     else:
  146         # String values other than booleans should be returned as it is, so that
  147         # schema validation will raise exceptions appropriately.
  148         return param
  149
  ```
  --- 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/core/controllers/payload_validator.py b/core/controllers/payload_validator.py
  --- a/core/controllers/payload_validator.py
  +++ b/core/controllers/payload_validator.py
  @@ -81,9 +81,7 @@
       errors = []
       # Dictionary to hold normalized values of arguments after validation.
       normalized_values = {}
  -
       for arg_key, arg_schema in handler_args_schemas.items():
  -
           if arg_key not in handler_args or handler_args[arg_key] is None:
               if 'default_value' in arg_schema:
                   if arg_schema['default_value'] is None:
  
verification_info: {"golden_diff": "diff --git a/core/controllers/payload_validator.py b/core/controllers/payload_validator.py\n--- a/core/controllers/payload_validator.py\n+++ b/core/controllers/payload_validator.py\n@@ -81,9 +81,7 @@\n     errors = []\n     # Dictionary to hold normalized values of arguments after validation.\n     normalized_values = {}\n-\n     for arg_key, arg_schema in handler_args_schemas.items():\n-\n         if arg_key not in handler_args or handler_args[arg_key] is None:\n             if 'default_value' in arg_schema:\n                 if arg_schema['default_value'] is None:\n", "issue": "[Contributor Dashboard] Unable to remove question contribution rights in admin dashboard\nWe're seeing `InvalidInputException\r\nSchema validation for 'language_code' failed: Validation failed: is_supported_audio_language_code ({}) for object null` when trying to remove question contribution rights.\r\n\r\n<img width=\"1272\" alt=\"Screen Shot 2021-11-08 at 4 49 25 PM\" src=\"https://user-images.githubusercontent.com/9004726/140823762-9b72375e-4237-4d2f-a2d2-c06af3e375d8.png\">\r\n\r\n\n", "before_files": [{"content": "# coding: utf-8\n\n# Copyright 2021 The Oppia Authors. All Rights Reserved.\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\n\"\"\"Validates handler args against its schema by calling schema utils.\nAlso contains a list of handler class names which does not contain the schema.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom core import schema_utils\n\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\n\n# Here Dict[str, Any] is used for arg_schema because the value field of the\n# schema is itself a dict that can further contain several nested dicts.\ndef get_schema_type(arg_schema: Dict[str, Any]) -> str:\n    \"\"\"Returns the schema type for an argument.\n\n    Args:\n        arg_schema: dict(str, *). Schema for an argument.\n\n    Returns:\n        str. Returns schema type by extracting it from schema.\n    \"\"\"\n    return arg_schema['schema']['type']\n\n\n# Here Dict[str, Any] is used for arg_schema because the value field of the\n# schema is itself a dict that can further contain several nested dicts.\ndef get_corresponding_key_for_object(arg_schema: Dict[str, Any]) -> str:\n    \"\"\"Returns the new key for an argument from its schema.\n\n    Args:\n        arg_schema: dict(str, *). Schema for an argument.\n\n    Returns:\n        str. The new argument name.\n    \"\"\"\n    return arg_schema['schema']['new_key_for_argument']\n\n\n# This function recursively uses the schema dictionary and handler_args, and\n# passes their values to itself as arguments, so their type is Any.\n# See: https://github.com/python/mypy/issues/731\ndef validate_arguments_against_schema(\n    handler_args: Any,\n    handler_args_schemas: Any,\n    allowed_extra_args: bool,\n    allow_string_to_bool_conversion: bool = False\n) -> Tuple[Dict[str, Any], List[str]]:\n    \"\"\"Calls schema utils for normalization of object against its schema\n    and collects all the errors.\n\n    Args:\n        handler_args: *. Object for normalization.\n        handler_args_schemas: dict. Schema for args.\n        allowed_extra_args: bool. Whether extra args are allowed in handler.\n        allow_string_to_bool_conversion: bool. Whether to allow string to\n            boolean coversion.\n\n    Returns:\n        *. A two tuple, where the first element represents the normalized value\n        in dict format and the second element represents the lists of errors\n        after validation.\n    \"\"\"\n    # Collect all errors and present them at once.\n    errors = []\n    # Dictionary to hold normalized values of arguments after validation.\n    normalized_values = {}\n\n    for arg_key, arg_schema in handler_args_schemas.items():\n\n        if arg_key not in handler_args or handler_args[arg_key] is None:\n            if 'default_value' in arg_schema:\n                if arg_schema['default_value'] is None:\n                    # Skip validation because the argument is optional.\n                    continue\n\n                if arg_schema['default_value'] is not None:\n                    handler_args[arg_key] = arg_schema['default_value']\n            else:\n                errors.append('Missing key in handler args: %s.' % arg_key)\n                continue\n\n        # Below normalization is for arguments which are expected to be boolean\n        # but from API request they are received as string type.\n        if (\n                allow_string_to_bool_conversion and\n                get_schema_type(arg_schema) == schema_utils.SCHEMA_TYPE_BOOL\n                and isinstance(handler_args[arg_key], str)\n        ):\n            handler_args[arg_key] = (\n                convert_string_to_bool(handler_args[arg_key]))\n\n        try:\n            normalized_value = schema_utils.normalize_against_schema(\n                handler_args[arg_key], arg_schema['schema'])\n\n            # Modification of argument name if new_key_for_argument\n            # field is present in the schema.\n            if 'new_key_for_argument' in arg_schema['schema']:\n                arg_key = get_corresponding_key_for_object(arg_schema)\n            normalized_values[arg_key] = normalized_value\n        except Exception as e:\n            errors.append(\n                'Schema validation for \\'%s\\' failed: %s' % (arg_key, e))\n\n    extra_args = set(handler_args.keys()) - set(handler_args_schemas.keys())\n\n    if not allowed_extra_args and extra_args:\n        errors.append('Found extra args: %s.' % (list(extra_args)))\n\n    return normalized_values, errors\n\n\ndef convert_string_to_bool(param: str) -> Optional[Union[bool, str]]:\n    \"\"\"Converts a request param of type string into expected bool type.\n\n    Args:\n        param: str. The params which needs normalization.\n\n    Returns:\n        bool. Converts the string param into its expected bool type.\n    \"\"\"\n    case_insensitive_param = param.lower()\n\n    if case_insensitive_param == 'true':\n        return True\n    elif case_insensitive_param == 'false':\n        return False\n    else:\n        # String values other than booleans should be returned as it is, so that\n        # schema validation will raise exceptions appropriately.\n        return param\n", "path": "core/controllers/payload_validator.py"}], "after_files": [{"content": "# coding: utf-8\n\n# Copyright 2021 The Oppia Authors. All Rights Reserved.\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\n\"\"\"Validates handler args against its schema by calling schema utils.\nAlso contains a list of handler class names which does not contain the schema.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom core import schema_utils\n\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\n\n# Here Dict[str, Any] is used for arg_schema because the value field of the\n# schema is itself a dict that can further contain several nested dicts.\ndef get_schema_type(arg_schema: Dict[str, Any]) -> str:\n    \"\"\"Returns the schema type for an argument.\n\n    Args:\n        arg_schema: dict(str, *). Schema for an argument.\n\n    Returns:\n        str. Returns schema type by extracting it from schema.\n    \"\"\"\n    return arg_schema['schema']['type']\n\n\n# Here Dict[str, Any] is used for arg_schema because the value field of the\n# schema is itself a dict that can further contain several nested dicts.\ndef get_corresponding_key_for_object(arg_schema: Dict[str, Any]) -> str:\n    \"\"\"Returns the new key for an argument from its schema.\n\n    Args:\n        arg_schema: dict(str, *). Schema for an argument.\n\n    Returns:\n        str. The new argument name.\n    \"\"\"\n    return arg_schema['schema']['new_key_for_argument']\n\n\n# This function recursively uses the schema dictionary and handler_args, and\n# passes their values to itself as arguments, so their type is Any.\n# See: https://github.com/python/mypy/issues/731\ndef validate_arguments_against_schema(\n    handler_args: Any,\n    handler_args_schemas: Any,\n    allowed_extra_args: bool,\n    allow_string_to_bool_conversion: bool = False\n) -> Tuple[Dict[str, Any], List[str]]:\n    \"\"\"Calls schema utils for normalization of object against its schema\n    and collects all the errors.\n\n    Args:\n        handler_args: *. Object for normalization.\n        handler_args_schemas: dict. Schema for args.\n        allowed_extra_args: bool. Whether extra args are allowed in handler.\n        allow_string_to_bool_conversion: bool. Whether to allow string to\n            boolean coversion.\n\n    Returns:\n        *. A two tuple, where the first element represents the normalized value\n        in dict format and the second element represents the lists of errors\n        after validation.\n    \"\"\"\n    # Collect all errors and present them at once.\n    errors = []\n    # Dictionary to hold normalized values of arguments after validation.\n    normalized_values = {}\n    for arg_key, arg_schema in handler_args_schemas.items():\n        if arg_key not in handler_args or handler_args[arg_key] is None:\n            if 'default_value' in arg_schema:\n                if arg_schema['default_value'] is None:\n                    # Skip validation because the argument is optional.\n                    continue\n\n                if arg_schema['default_value'] is not None:\n                    handler_args[arg_key] = arg_schema['default_value']\n            else:\n                errors.append('Missing key in handler args: %s.' % arg_key)\n                continue\n\n        # Below normalization is for arguments which are expected to be boolean\n        # but from API request they are received as string type.\n        if (\n                allow_string_to_bool_conversion and\n                get_schema_type(arg_schema) == schema_utils.SCHEMA_TYPE_BOOL\n                and isinstance(handler_args[arg_key], str)\n        ):\n            handler_args[arg_key] = (\n                convert_string_to_bool(handler_args[arg_key]))\n\n        try:\n            normalized_value = schema_utils.normalize_against_schema(\n                handler_args[arg_key], arg_schema['schema'])\n\n            # Modification of argument name if new_key_for_argument\n            # field is present in the schema.\n            if 'new_key_for_argument' in arg_schema['schema']:\n                arg_key = get_corresponding_key_for_object(arg_schema)\n            normalized_values[arg_key] = normalized_value\n        except Exception as e:\n            errors.append(\n                'Schema validation for \\'%s\\' failed: %s' % (arg_key, e))\n\n    extra_args = set(handler_args.keys()) - set(handler_args_schemas.keys())\n\n    if not allowed_extra_args and extra_args:\n        errors.append('Found extra args: %s.' % (list(extra_args)))\n\n    return normalized_values, errors\n\n\ndef convert_string_to_bool(param: str) -> Optional[Union[bool, str]]:\n    \"\"\"Converts a request param of type string into expected bool type.\n\n    Args:\n        param: str. The params which needs normalization.\n\n    Returns:\n        bool. Converts the string param into its expected bool type.\n    \"\"\"\n    case_insensitive_param = param.lower()\n\n    if case_insensitive_param == 'true':\n        return True\n    elif case_insensitive_param == 'false':\n        return False\n    else:\n        # String values other than booleans should be returned as it is, so that\n        # schema validation will raise exceptions appropriately.\n        return param\n", "path": "core/controllers/payload_validator.py"}]}