# Buggy code
async def train_parsers(self, skills):
    """Train the parsers.

    Args:
        skills (list): A list of all the loaded skills.

    """
    if "parsers" in self.config:
        parsers = self.config["parsers"] or {}
        rasanlu = parsers.get("rasanlu")
        if rasanlu and rasanlu["enabled"]:
            await train_rasanlu(rasanlu, skills)


# Traceback (KeyError)
INFO opsdroid.logging: ========================================
INFO opsdroid.logging: Started opsdroid v0.8.1+833.g5c8dbb7.dirty.
INFO opsdroid: ========================================
INFO opsdroid: You can customise your opsdroid by modifying your configuration.yaml.
INFO opsdroid: Read more at: http://opsdroid.readthedocs.io/#configuration
INFO opsdroid: Watch the Get Started Videos at: http://bit.ly/2fnC0Fh
INFO opsdroid: Install Opsdroid Desktop at:
https://github.com/opsdroid/opsdroid-desktop/releases
INFO opsdroid: ========================================
DEBUG asyncio: Using selector: KqueueSelector
DEBUG opsdroid.loader: Loaded loader.
DEBUG opsdroid.loader: Loading modules from config...
WARNING opsdroid.loader: No databases in configuration. This will cause skills which store things in memory to lose data when opsdroid is restarted.
DEBUG opsdroid.loader: Loading parsers modules...
DEBUG opsdroid.loader: Loaded parsers: opsdroid.parsers.dialogflow.
DEBUG opsdroid.loader: Loading skill modules...
DEBUG opsdroid.loader: Updating dance...
DEBUG opsdroid.loader: b'Already up to date.'
DEBUG opsdroid.loader: b'Current branch master is up to date.'
DEBUG opsdroid.loader: Couldn't find the file requirements.txt, skipping.
DEBUG opsdroid.loader: Loaded skill: opsdroid-modules.skill.dance.
DEBUG opsdroid.loader: Updating hello...
DEBUG opsdroid.loader: b'Already up to date.'
DEBUG opsdroid.loader: b'Current branch master is up to date.'
DEBUG opsdroid.loader: Couldn't find the file requirements.txt, skipping.
DEBUG opsdroid.loader: Loaded skill: opsdroid-modules.skill.hello.
DEBUG opsdroid.loader: Updating loudnoises...
DEBUG opsdroid.loader: b'Already up to date.'
DEBUG opsdroid.loader: b'Current branch master is up to date.'
DEBUG opsdroid.loader: Couldn't find the file requirements.txt, skipping.
DEBUG opsdroid.loader: Loaded skill: opsdroid-modules.skill.loudnoises.
DEBUG opsdroid.loader: Updating seen...
DEBUG opsdroid.loader: b'Already up to date.'
DEBUG opsdroid.loader: b'Current branch master is up to date.'
DEBUG opsdroid.loader: b'Processing /Users/fabiorosado/Library/Caches/pip/wheels/c8/61/2f/47076152dc9487142c2ae48754c87539ff0993decf0fc2f198/ago-0.0.93-py3-none-any.whl'
DEBUG opsdroid.loader: b'Installing collected packages: ago'
DEBUG opsdroid.loader: b'Successfully installed ago-0.0.93'
DEBUG opsdroid.loader: b'WARNING: Target directory /Users/fabiorosado/Library/Application Support/opsdroid/site-packages/ago.py already exists. Specify --upgrade to force replacement.'
DEBUG opsdroid.loader: b'WARNING: Target directory /Users/fabiorosado/Library/Application Support/opsdroid/site-packages/__pycache__ already exists. Specify --upgrade to force replacement.'
DEBUG opsdroid.loader: b'WARNING: Target directory /Users/fabiorosado/Library/Application Support/opsdroid/site-packages/ago-0.0.93.dist-info already exists. Specify --upgrade to force replacement.'
DEBUG opsdroid.loader: Loaded skill: opsdroid-modules.skill.seen.
DEBUG opsdroid.loader: Loading connector modules...
DEBUG opsdroid.loader: Loaded connector: opsdroid.connector.websocket.
DEBUG opsdroid.loader: Loaded connector: opsdroid.connector.shell.
DEBUG opsdroid.core: Loaded 4 skills.
DEBUG opsdroid.connector.websocket: Starting Websocket connector.
DEBUG opsdroid.connector.shell: Loaded shell Connector.
DEBUG opsdroid.connector.shell: Connecting to shell.
INFO opsdroid.web: Started web server on http://0.0.0.0:8080
INFO opsdroid.core: Opsdroid is now running, press ctrl+c to exit.
opsdroid> DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
hi
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=hi)>.
DEBUG opsdroid.core: Processing parsers...
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
DEBUG asyncio: Using selector: KqueueSelector
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/__main__.py", line 12, in <module>
init()
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/__main__.py", line 9, in init
opsdroid.cli.cli()
File "/Users/fabiorosado/.local/share/virtualenvs/opsdroid-AmeH9qot/lib/python3.7/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/Users/fabiorosado/.local/share/virtualenvs/opsdroid-AmeH9qot/lib/python3.7/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/fabiorosado/.local/share/virtualenvs/opsdroid-AmeH9qot/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/fabiorosado/.local/share/virtualenvs/opsdroid-AmeH9qot/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/fabiorosado/.local/share/virtualenvs/opsdroid-AmeH9qot/lib/python3.7/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/cli/start.py", line 42, in start
opsdroid.run()
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/core.py", line 165, in run
self.eventloop.run_until_complete(asyncio.gather(*pending))
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 583, in run_until_complete
return future.result()
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/connector/shell/__init__.py", line 93, in _parse_message
await self.parseloop()
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/connector/shell/__init__.py", line 88, in parseloop
await self.opsdroid.parse(message)
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/core.py", line 498, in parse
ranked_skills = await self.get_ranked_skills(unconstrained_skills, event)
File "/Users/fabiorosado/Documents/GitHub.tmp/opsdroid/opsdroid/core.py", line 429, in get_ranked_skills
if dialogflow and dialogflow["enabled"]:
KeyError: 'enabled'
ERROR: Unhandled exception in opsdroid, exiting...
ERROR: Unhandled exception in opsdroid, exiting...

# Fixed code
async def train_parsers(self, skills):
    """Train the parsers.

    Args:
        skills (list): A list of all the loaded skills.

    """
    if "parsers" in self.modules:
        parsers = self.modules.get("parsers", {})
        rasanlu = get_parser_config("rasanlu", parsers)
        if rasanlu and rasanlu["enabled"]:
            await train_rasanlu(rasanlu, skills)