We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
completion bug when completion unresolved values
`python demos/6_sweep/experiment.py  hydra/launcher=fairtask hydra.launcher.params.queue=local hydra.launcher.params.queues.slurm.params.<TAB>`

->
KeyError: "str interpolation key 'hydra.job.num_jobs' not found"
completion bug when completion unresolved values
`python demos/6_sweep/experiment.py  hydra/launcher=fairtask hydra.launcher.params.queue=local hydra.launcher.params.queues.slurm.params.<TAB>`

->
KeyError: "str interpolation key 'hydra.job.num_jobs' not found"

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hydra/plugins/completion_plugin.py`
Content:
```
1 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
2 import os
3 import sys
4 from abc import ABCMeta
5 from abc import abstractmethod
6 import six
7 from omegaconf import DictConfig, ListConfig, Config
8 
9 from hydra.plugins import Plugin
10 
11 
12 @six.add_metaclass(ABCMeta)
13 class CompletionPlugin(Plugin):
14     def __init__(self, config_loader):
15         self.config_loader = config_loader
16 
17     def install(self):
18         raise NotImplementedError()
19 
20     def uninstall(self):
21         raise NotImplementedError()
22 
23     @abstractmethod
24     def provides(self):
25         """
26         :return: the name of the shell this plugin provides completion for
27         """
28         return None
29 
30     def query(self):
31         raise NotImplementedError()
32 
33     @staticmethod
34     def _get_filename(fname):
35         last = fname.rfind("=")
36         if last != -1:
37             key_eq = fname[0 : last + 1]
38             fname = fname[last + 1 :]
39             prefixes = [".", "/", "\\", "./", ".\\"]
40             if sys.platform.startswith("win"):
41                 for drive in range(ord("a"), ord("z")):
42                     prefixes.append("{}:".format(chr(drive)))
43 
44             if not fname:
45                 return None, None
46             lowerfilename = fname.lower()
47             for prefix in prefixes:
48                 if lowerfilename.startswith(prefix):
49                     return key_eq, fname
50         return None, None
51 
52     @staticmethod
53     def complete_files(word):
54         if os.path.isdir(word):
55             dirname = word
56             files = os.listdir(word)
57             file_prefix = ""
58         else:
59             dirname = os.path.dirname(word)
60             if os.path.isdir(dirname):
61                 files = os.listdir(dirname)
62             else:
63                 files = []
64             file_prefix = os.path.basename(word)
65         ret = []
66         for file in files:
67             if file.startswith(file_prefix):
68                 ret.append(os.path.join(dirname, file))
69         return ret
70 
71     @staticmethod
72     def _get_matches(config, word):
73         def str_rep(in_key, in_value):
74             if isinstance(in_value, Config):
75                 return "{}.".format(in_key)
76             else:
77                 return "{}=".format(in_key)
78 
79         if config is None:
80             return []
81         elif isinstance(config, Config):
82             matches = []
83             if word.endswith(".") or word.endswith("="):
84                 exact_key = word[0:-1]
85                 conf_node = config.select(exact_key)
86                 if conf_node is not None:
87                     if isinstance(conf_node, Config):
88                         key_matches = CompletionPlugin._get_matches(conf_node, "")
89                     else:
90                         # primitive
91                         if isinstance(conf_node, bool):
92                             conf_node = str(conf_node).lower()
93                         key_matches = [conf_node]
94                 else:
95                     key_matches = []
96 
97                 matches.extend(["{}{}".format(word, match) for match in key_matches])
98             else:
99                 last_dot = word.rfind(".")
100                 if last_dot != -1:
101                     base_key = word[0:last_dot]
102                     partial_key = word[last_dot + 1 :]
103                     conf_node = config.select(base_key)
104                     key_matches = CompletionPlugin._get_matches(conf_node, partial_key)
105                     matches.extend(
106                         ["{}.{}".format(base_key, match) for match in key_matches]
107                     )
108                 else:
109                     if isinstance(config, DictConfig):
110                         for key, value in config.items():
111                             if key.startswith(word):
112                                 matches.append(str_rep(key, value))
113                     elif isinstance(config, ListConfig):
114                         for idx, value in enumerate(config):
115                             if str(idx).startswith(word):
116                                 matches.append(str_rep(idx, value))
117         else:
118             assert False, "Object is not an instance of config : {}".format(
119                 type(config)
120             )
121 
122         return matches
123 
124     def _query_config_groups(self, word):
125         last_eq_index = word.rfind("=")
126         last_slash_index = word.rfind("/")
127         exact_match = False
128         if last_eq_index != -1:
129             parent_group = word[0:last_eq_index]
130             file_type = "file"
131         else:
132             file_type = "dir"
133             if last_slash_index == -1:
134                 parent_group = ""
135             else:
136                 parent_group = word[0:last_slash_index]
137 
138         all_matched_groups = self.config_loader.get_group_options(
139             parent_group, file_type=file_type
140         )
141         matched_groups = []
142         if file_type == "file":
143             for match in all_matched_groups:
144                 name = (
145                     "{}={}".format(parent_group, match) if parent_group != "" else match
146                 )
147                 if name.startswith(word):
148                     matched_groups.append(name)
149                 exact_match = True
150         elif file_type == "dir":
151             for match in all_matched_groups:
152                 name = (
153                     "{}/{}".format(parent_group, match) if parent_group != "" else match
154                 )
155                 if name.startswith(word):
156                     files = self.config_loader.get_group_options(name, file_type="file")
157                     dirs = self.config_loader.get_group_options(name, file_type="dir")
158                     if len(dirs) == 0 and len(files) > 0:
159                         name = name + "="
160                     elif len(dirs) > 0 and len(files) == 0:
161                         name = name + "/"
162                     matched_groups.append(name)
163 
164         return matched_groups, exact_match
165 
166     def _query(self, line):
167         from .._internal.utils import get_args
168 
169         split = line.split(" ")
170         parsed_args = get_args(split)
171         args = parsed_args.overrides
172         if len(args) > 0:
173             word = args[-1]
174             words = args[0:-1]
175         else:
176             word = ""
177             words = []
178 
179         config = self.config_loader.load_configuration(words)
180 
181         fname_prefix, filename = CompletionPlugin._get_filename(word)
182         if filename is not None:
183             result = CompletionPlugin.complete_files(filename)
184             result = [fname_prefix + file for file in result]
185         else:
186             matched_groups, exact_match = self._query_config_groups(word)
187             config_matches = []
188             if not exact_match:
189                 config_matches = CompletionPlugin._get_matches(config, word)
190             result = list(set(matched_groups + config_matches))
191 
192         return sorted(result)
193 
194 
195 @six.add_metaclass(ABCMeta)
196 class DefaultCompletionPlugin(CompletionPlugin):
197     """
198     A concrete instance of CompletionPlugin that is used for testing.
199     """
200 
201     def provides(self):
202         return None
203
```
--- 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/hydra/plugins/completion_plugin.py b/hydra/plugins/completion_plugin.py
--- a/hydra/plugins/completion_plugin.py
+++ b/hydra/plugins/completion_plugin.py
@@ -4,7 +4,7 @@
 from abc import ABCMeta
 from abc import abstractmethod
 import six
-from omegaconf import DictConfig, ListConfig, Config
+from omegaconf import DictConfig, ListConfig, Config, MissingMandatoryValue
 
 from hydra.plugins import Plugin
 
@@ -82,7 +82,10 @@
             matches = []
             if word.endswith(".") or word.endswith("="):
                 exact_key = word[0:-1]
-                conf_node = config.select(exact_key)
+                try:
+                    conf_node = config.select(exact_key)
+                except MissingMandatoryValue:
+                    conf_node = ""
                 if conf_node is not None:
                     if isinstance(conf_node, Config):
                         key_matches = CompletionPlugin._get_matches(conf_node, "")
@@ -107,7 +110,7 @@
                     )
                 else:
                     if isinstance(config, DictConfig):
-                        for key, value in config.items():
+                        for key, value in config.items(resolve=False):
                             if key.startswith(word):
                                 matches.append(str_rep(key, value))
                     elif isinstance(config, ListConfig):

{"golden_diff": "diff --git a/hydra/plugins/completion_plugin.py b/hydra/plugins/completion_plugin.py\n--- a/hydra/plugins/completion_plugin.py\n+++ b/hydra/plugins/completion_plugin.py\n@@ -4,7 +4,7 @@\n from abc import ABCMeta\n from abc import abstractmethod\n import six\n-from omegaconf import DictConfig, ListConfig, Config\n+from omegaconf import DictConfig, ListConfig, Config, MissingMandatoryValue\n \n from hydra.plugins import Plugin\n \n@@ -82,7 +82,10 @@\n             matches = []\n             if word.endswith(\".\") or word.endswith(\"=\"):\n                 exact_key = word[0:-1]\n-                conf_node = config.select(exact_key)\n+                try:\n+                    conf_node = config.select(exact_key)\n+                except MissingMandatoryValue:\n+                    conf_node = \"\"\n                 if conf_node is not None:\n                     if isinstance(conf_node, Config):\n                         key_matches = CompletionPlugin._get_matches(conf_node, \"\")\n@@ -107,7 +110,7 @@\n                     )\n                 else:\n                     if isinstance(config, DictConfig):\n-                        for key, value in config.items():\n+                        for key, value in config.items(resolve=False):\n                             if key.startswith(word):\n                                 matches.append(str_rep(key, value))\n                     elif isinstance(config, ListConfig):\n", "issue": "completion bug when completion unresolved values\n`python demos/6_sweep/experiment.py  hydra/launcher=fairtask hydra.launcher.params.queue=local hydra.launcher.params.queues.slurm.params.<TAB>`\r\n\r\n->\r\nKeyError: \"str interpolation key 'hydra.job.num_jobs' not found\"\ncompletion bug when completion unresolved values\n`python demos/6_sweep/experiment.py  hydra/launcher=fairtask hydra.launcher.params.queue=local hydra.launcher.params.queues.slurm.params.<TAB>`\r\n\r\n->\r\nKeyError: \"str interpolation key 'hydra.job.num_jobs' not found\"\n", "before_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport os\nimport sys\nfrom abc import ABCMeta\nfrom abc import abstractmethod\nimport six\nfrom omegaconf import DictConfig, ListConfig, Config\n\nfrom hydra.plugins import Plugin\n\n\n@six.add_metaclass(ABCMeta)\nclass CompletionPlugin(Plugin):\n    def __init__(self, config_loader):\n        self.config_loader = config_loader\n\n    def install(self):\n        raise NotImplementedError()\n\n    def uninstall(self):\n        raise NotImplementedError()\n\n    @abstractmethod\n    def provides(self):\n        \"\"\"\n        :return: the name of the shell this plugin provides completion for\n        \"\"\"\n        return None\n\n    def query(self):\n        raise NotImplementedError()\n\n    @staticmethod\n    def _get_filename(fname):\n        last = fname.rfind(\"=\")\n        if last != -1:\n            key_eq = fname[0 : last + 1]\n            fname = fname[last + 1 :]\n            prefixes = [\".\", \"/\", \"\\\\\", \"./\", \".\\\\\"]\n            if sys.platform.startswith(\"win\"):\n                for drive in range(ord(\"a\"), ord(\"z\")):\n                    prefixes.append(\"{}:\".format(chr(drive)))\n\n            if not fname:\n                return None, None\n            lowerfilename = fname.lower()\n            for prefix in prefixes:\n                if lowerfilename.startswith(prefix):\n                    return key_eq, fname\n        return None, None\n\n    @staticmethod\n    def complete_files(word):\n        if os.path.isdir(word):\n            dirname = word\n            files = os.listdir(word)\n            file_prefix = \"\"\n        else:\n            dirname = os.path.dirname(word)\n            if os.path.isdir(dirname):\n                files = os.listdir(dirname)\n            else:\n                files = []\n            file_prefix = os.path.basename(word)\n        ret = []\n        for file in files:\n            if file.startswith(file_prefix):\n                ret.append(os.path.join(dirname, file))\n        return ret\n\n    @staticmethod\n    def _get_matches(config, word):\n        def str_rep(in_key, in_value):\n            if isinstance(in_value, Config):\n                return \"{}.\".format(in_key)\n            else:\n                return \"{}=\".format(in_key)\n\n        if config is None:\n            return []\n        elif isinstance(config, Config):\n            matches = []\n            if word.endswith(\".\") or word.endswith(\"=\"):\n                exact_key = word[0:-1]\n                conf_node = config.select(exact_key)\n                if conf_node is not None:\n                    if isinstance(conf_node, Config):\n                        key_matches = CompletionPlugin._get_matches(conf_node, \"\")\n                    else:\n                        # primitive\n                        if isinstance(conf_node, bool):\n                            conf_node = str(conf_node).lower()\n                        key_matches = [conf_node]\n                else:\n                    key_matches = []\n\n                matches.extend([\"{}{}\".format(word, match) for match in key_matches])\n            else:\n                last_dot = word.rfind(\".\")\n                if last_dot != -1:\n                    base_key = word[0:last_dot]\n                    partial_key = word[last_dot + 1 :]\n                    conf_node = config.select(base_key)\n                    key_matches = CompletionPlugin._get_matches(conf_node, partial_key)\n                    matches.extend(\n                        [\"{}.{}\".format(base_key, match) for match in key_matches]\n                    )\n                else:\n                    if isinstance(config, DictConfig):\n                        for key, value in config.items():\n                            if key.startswith(word):\n                                matches.append(str_rep(key, value))\n                    elif isinstance(config, ListConfig):\n                        for idx, value in enumerate(config):\n                            if str(idx).startswith(word):\n                                matches.append(str_rep(idx, value))\n        else:\n            assert False, \"Object is not an instance of config : {}\".format(\n                type(config)\n            )\n\n        return matches\n\n    def _query_config_groups(self, word):\n        last_eq_index = word.rfind(\"=\")\n        last_slash_index = word.rfind(\"/\")\n        exact_match = False\n        if last_eq_index != -1:\n            parent_group = word[0:last_eq_index]\n            file_type = \"file\"\n        else:\n            file_type = \"dir\"\n            if last_slash_index == -1:\n                parent_group = \"\"\n            else:\n                parent_group = word[0:last_slash_index]\n\n        all_matched_groups = self.config_loader.get_group_options(\n            parent_group, file_type=file_type\n        )\n        matched_groups = []\n        if file_type == \"file\":\n            for match in all_matched_groups:\n                name = (\n                    \"{}={}\".format(parent_group, match) if parent_group != \"\" else match\n                )\n                if name.startswith(word):\n                    matched_groups.append(name)\n                exact_match = True\n        elif file_type == \"dir\":\n            for match in all_matched_groups:\n                name = (\n                    \"{}/{}\".format(parent_group, match) if parent_group != \"\" else match\n                )\n                if name.startswith(word):\n                    files = self.config_loader.get_group_options(name, file_type=\"file\")\n                    dirs = self.config_loader.get_group_options(name, file_type=\"dir\")\n                    if len(dirs) == 0 and len(files) > 0:\n                        name = name + \"=\"\n                    elif len(dirs) > 0 and len(files) == 0:\n                        name = name + \"/\"\n                    matched_groups.append(name)\n\n        return matched_groups, exact_match\n\n    def _query(self, line):\n        from .._internal.utils import get_args\n\n        split = line.split(\" \")\n        parsed_args = get_args(split)\n        args = parsed_args.overrides\n        if len(args) > 0:\n            word = args[-1]\n            words = args[0:-1]\n        else:\n            word = \"\"\n            words = []\n\n        config = self.config_loader.load_configuration(words)\n\n        fname_prefix, filename = CompletionPlugin._get_filename(word)\n        if filename is not None:\n            result = CompletionPlugin.complete_files(filename)\n            result = [fname_prefix + file for file in result]\n        else:\n            matched_groups, exact_match = self._query_config_groups(word)\n            config_matches = []\n            if not exact_match:\n                config_matches = CompletionPlugin._get_matches(config, word)\n            result = list(set(matched_groups + config_matches))\n\n        return sorted(result)\n\n\n@six.add_metaclass(ABCMeta)\nclass DefaultCompletionPlugin(CompletionPlugin):\n    \"\"\"\n    A concrete instance of CompletionPlugin that is used for testing.\n    \"\"\"\n\n    def provides(self):\n        return None\n", "path": "hydra/plugins/completion_plugin.py"}], "after_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport os\nimport sys\nfrom abc import ABCMeta\nfrom abc import abstractmethod\nimport six\nfrom omegaconf import DictConfig, ListConfig, Config, MissingMandatoryValue\n\nfrom hydra.plugins import Plugin\n\n\n@six.add_metaclass(ABCMeta)\nclass CompletionPlugin(Plugin):\n    def __init__(self, config_loader):\n        self.config_loader = config_loader\n\n    def install(self):\n        raise NotImplementedError()\n\n    def uninstall(self):\n        raise NotImplementedError()\n\n    @abstractmethod\n    def provides(self):\n        \"\"\"\n        :return: the name of the shell this plugin provides completion for\n        \"\"\"\n        return None\n\n    def query(self):\n        raise NotImplementedError()\n\n    @staticmethod\n    def _get_filename(fname):\n        last = fname.rfind(\"=\")\n        if last != -1:\n            key_eq = fname[0 : last + 1]\n            fname = fname[last + 1 :]\n            prefixes = [\".\", \"/\", \"\\\\\", \"./\", \".\\\\\"]\n            if sys.platform.startswith(\"win\"):\n                for drive in range(ord(\"a\"), ord(\"z\")):\n                    prefixes.append(\"{}:\".format(chr(drive)))\n\n            if not fname:\n                return None, None\n            lowerfilename = fname.lower()\n            for prefix in prefixes:\n                if lowerfilename.startswith(prefix):\n                    return key_eq, fname\n        return None, None\n\n    @staticmethod\n    def complete_files(word):\n        if os.path.isdir(word):\n            dirname = word\n            files = os.listdir(word)\n            file_prefix = \"\"\n        else:\n            dirname = os.path.dirname(word)\n            if os.path.isdir(dirname):\n                files = os.listdir(dirname)\n            else:\n                files = []\n            file_prefix = os.path.basename(word)\n        ret = []\n        for file in files:\n            if file.startswith(file_prefix):\n                ret.append(os.path.join(dirname, file))\n        return ret\n\n    @staticmethod\n    def _get_matches(config, word):\n        def str_rep(in_key, in_value):\n            if isinstance(in_value, Config):\n                return \"{}.\".format(in_key)\n            else:\n                return \"{}=\".format(in_key)\n\n        if config is None:\n            return []\n        elif isinstance(config, Config):\n            matches = []\n            if word.endswith(\".\") or word.endswith(\"=\"):\n                exact_key = word[0:-1]\n                try:\n                    conf_node = config.select(exact_key)\n                except MissingMandatoryValue:\n                    conf_node = \"\"\n                if conf_node is not None:\n                    if isinstance(conf_node, Config):\n                        key_matches = CompletionPlugin._get_matches(conf_node, \"\")\n                    else:\n                        # primitive\n                        if isinstance(conf_node, bool):\n                            conf_node = str(conf_node).lower()\n                        key_matches = [conf_node]\n                else:\n                    key_matches = []\n\n                matches.extend([\"{}{}\".format(word, match) for match in key_matches])\n            else:\n                last_dot = word.rfind(\".\")\n                if last_dot != -1:\n                    base_key = word[0:last_dot]\n                    partial_key = word[last_dot + 1 :]\n                    conf_node = config.select(base_key)\n                    key_matches = CompletionPlugin._get_matches(conf_node, partial_key)\n                    matches.extend(\n                        [\"{}.{}\".format(base_key, match) for match in key_matches]\n                    )\n                else:\n                    if isinstance(config, DictConfig):\n                        for key, value in config.items(resolve=False):\n                            if key.startswith(word):\n                                matches.append(str_rep(key, value))\n                    elif isinstance(config, ListConfig):\n                        for idx, value in enumerate(config):\n                            if str(idx).startswith(word):\n                                matches.append(str_rep(idx, value))\n        else:\n            assert False, \"Object is not an instance of config : {}\".format(\n                type(config)\n            )\n\n        return matches\n\n    def _query_config_groups(self, word):\n        last_eq_index = word.rfind(\"=\")\n        last_slash_index = word.rfind(\"/\")\n        exact_match = False\n        if last_eq_index != -1:\n            parent_group = word[0:last_eq_index]\n            file_type = \"file\"\n        else:\n            file_type = \"dir\"\n            if last_slash_index == -1:\n                parent_group = \"\"\n            else:\n                parent_group = word[0:last_slash_index]\n\n        all_matched_groups = self.config_loader.get_group_options(\n            parent_group, file_type=file_type\n        )\n        matched_groups = []\n        if file_type == \"file\":\n            for match in all_matched_groups:\n                name = (\n                    \"{}={}\".format(parent_group, match) if parent_group != \"\" else match\n                )\n                if name.startswith(word):\n                    matched_groups.append(name)\n                exact_match = True\n        elif file_type == \"dir\":\n            for match in all_matched_groups:\n                name = (\n                    \"{}/{}\".format(parent_group, match) if parent_group != \"\" else match\n                )\n                if name.startswith(word):\n                    files = self.config_loader.get_group_options(name, file_type=\"file\")\n                    dirs = self.config_loader.get_group_options(name, file_type=\"dir\")\n                    if len(dirs) == 0 and len(files) > 0:\n                        name = name + \"=\"\n                    elif len(dirs) > 0 and len(files) == 0:\n                        name = name + \"/\"\n                    matched_groups.append(name)\n\n        return matched_groups, exact_match\n\n    def _query(self, line):\n        from .._internal.utils import get_args\n\n        split = line.split(\" \")\n        parsed_args = get_args(split)\n        args = parsed_args.overrides\n        if len(args) > 0:\n            word = args[-1]\n            words = args[0:-1]\n        else:\n            word = \"\"\n            words = []\n\n        config = self.config_loader.load_configuration(words)\n\n        fname_prefix, filename = CompletionPlugin._get_filename(word)\n        if filename is not None:\n            result = CompletionPlugin.complete_files(filename)\n            result = [fname_prefix + file for file in result]\n        else:\n            matched_groups, exact_match = self._query_config_groups(word)\n            config_matches = []\n            if not exact_match:\n                config_matches = CompletionPlugin._get_matches(config, word)\n            result = list(set(matched_groups + config_matches))\n\n        return sorted(result)\n\n\n@six.add_metaclass(ABCMeta)\nclass DefaultCompletionPlugin(CompletionPlugin):\n    \"\"\"\n    A concrete instance of CompletionPlugin that is used for testing.\n    \"\"\"\n\n    def provides(self):\n        return None\n", "path": "hydra/plugins/completion_plugin.py"}]}