prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  keyfinder: Output parsing error
  ### Problem
  
  Running this command in verbose (`-vv`) mode:
  
  ``` sh
  $ beet -vv keyfinder anything
  ```
  
  Led to this problem:
  
  ```
  user configuration: /home/diomekes/.config/beets/config.yaml
  data directory: /home/diomekes/.config/beets
  plugin paths:
  Sending event: pluginload
  inline: adding item field disc_and_track
  library database: /home/diomekes/.config/beets/library.db
  library directory: /home/diomekes/media/music
  Sending event: library_opened
  Traceback (most recent call last):
    File "/usr/bin/beet", line 9, in <module>
      load_entry_point('beets==1.3.19', 'console_scripts', 'beet')()
    File "/usr/lib/python2.7/site-packages/beets/ui/__init__.py", line 1266, in main
      _raw_main(args)
    File "/usr/lib/python2.7/site-packages/beets/ui/__init__.py", line 1253, in _raw_main
      subcommand.func(lib, suboptions, subargs)
    File "/usr/lib/python2.7/site-packages/beetsplug/keyfinder.py", line 48, in command
      self.find_key(lib.items(ui.decargs(args)), write=ui.should_write())
    File "/usr/lib/python2.7/site-packages/beetsplug/keyfinder.py", line 74, in find_key
      key_raw = output.rsplit(None, 1)[-1]
  IndexError: list index out of range
  ```
  
  keyfinder-cli works if run directly
  ### Setup
  - OS:  archlinux
  - Python version: 2.7.12
  - beets version: 1.3.19
  - Turning off plugins made problem go away (yes/no): problem is with keyfinder plugin only
  - libkeyfinder-git 239.0a5ec7f-1
  - keyfinder-cli-git 49.40a41ab-1
  
  My configuration (output of `beet config`) is:
  
  ``` yaml
  ...
  keyfinder:
      bin: keyfinder-cli
      auto: yes
      overwrite: no
  
  plugins: badfiles chroma convert duplicates fetchart fromfilename fuzzy info inline keyfinder lastgenre lyrics mbcollection mbsync missing play random scrub smartplaylist zero
  ...
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `beetsplug/keyfinder.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 # This file is part of beets.
  3 # Copyright 2016, Thomas Scholtes.
  4 #
  5 # Permission is hereby granted, free of charge, to any person obtaining
  6 # a copy of this software and associated documentation files (the
  7 # "Software"), to deal in the Software without restriction, including
  8 # without limitation the rights to use, copy, modify, merge, publish,
  9 # distribute, sublicense, and/or sell copies of the Software, and to
  10 # permit persons to whom the Software is furnished to do so, subject to
  11 # the following conditions:
  12 #
  13 # The above copyright notice and this permission notice shall be
  14 # included in all copies or substantial portions of the Software.
  15 
  16 """Uses the `KeyFinder` program to add the `initial_key` field.
  17 """
  18 
  19 from __future__ import division, absolute_import, print_function
  20 
  21 import os.path
  22 import subprocess
  23 
  24 from beets import ui
  25 from beets import util
  26 from beets.plugins import BeetsPlugin
  27 
  28 
  29 class KeyFinderPlugin(BeetsPlugin):
  30 
  31     def __init__(self):
  32         super(KeyFinderPlugin, self).__init__()
  33         self.config.add({
  34             u'bin': u'KeyFinder',
  35             u'auto': True,
  36             u'overwrite': False,
  37         })
  38 
  39         if self.config['auto'].get(bool):
  40             self.import_stages = [self.imported]
  41 
  42     def commands(self):
  43         cmd = ui.Subcommand('keyfinder',
  44                             help=u'detect and add initial key from audio')
  45         cmd.func = self.command
  46         return [cmd]
  47 
  48     def command(self, lib, opts, args):
  49         self.find_key(lib.items(ui.decargs(args)), write=ui.should_write())
  50 
  51     def imported(self, session, task):
  52         self.find_key(task.imported_items())
  53 
  54     def find_key(self, items, write=False):
  55         overwrite = self.config['overwrite'].get(bool)
  56         command = [self.config['bin'].as_str()]
  57         # The KeyFinder GUI program needs the -f flag before the path.
  58         # keyfinder-cli is similar, but just wants the path with no flag.
  59         if 'keyfinder-cli' not in os.path.basename(command[0]).lower():
  60             command.append('-f')
  61 
  62         for item in items:
  63             if item['initial_key'] and not overwrite:
  64                 continue
  65 
  66             try:
  67                 output = util.command_output(command + [util.syspath(
  68                                                         item.path)]).stdout
  69             except (subprocess.CalledProcessError, OSError) as exc:
  70                 self._log.error(u'execution failed: {0}', exc)
  71                 continue
  72             except UnicodeEncodeError:
  73                 # Workaround for Python 2 Windows bug.
  74                 # https://bugs.python.org/issue1759845
  75                 self._log.error(u'execution failed for Unicode path: {0!r}',
  76                                 item.path)
  77                 continue
  78 
  79             key_raw = output.rsplit(None, 1)[-1]
  80             try:
  81                 key = util.text_string(key_raw)
  82             except UnicodeDecodeError:
  83                 self._log.error(u'output is invalid UTF-8')
  84                 continue
  85 
  86             item['initial_key'] = key
  87             self._log.info(u'added computed initial key {0} for {1}',
  88                            key, util.displayable_path(item.path))
  89 
  90             if write:
  91                 item.try_write()
  92             item.store()
  93
  ```
  --- 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/beetsplug/keyfinder.py b/beetsplug/keyfinder.py
  --- a/beetsplug/keyfinder.py
  +++ b/beetsplug/keyfinder.py
  @@ -76,7 +76,14 @@
                                   item.path)
                   continue
   
  -            key_raw = output.rsplit(None, 1)[-1]
  +            try:
  +                key_raw = output.rsplit(None, 1)[-1]
  +            except IndexError:
  +                # Sometimes keyfinder-cli returns 0 but with no key, usually
  +                # when the file is silent or corrupt, so we log and skip.
  +                self._log.error(u'no key returned for path: {0}', item.path)
  +                continue
  +
               try:
                   key = util.text_string(key_raw)
               except UnicodeDecodeError:
  
verification_info: {"golden_diff": "diff --git a/beetsplug/keyfinder.py b/beetsplug/keyfinder.py\n--- a/beetsplug/keyfinder.py\n+++ b/beetsplug/keyfinder.py\n@@ -76,7 +76,14 @@\n                                 item.path)\n                 continue\n \n-            key_raw = output.rsplit(None, 1)[-1]\n+            try:\n+                key_raw = output.rsplit(None, 1)[-1]\n+            except IndexError:\n+                # Sometimes keyfinder-cli returns 0 but with no key, usually\n+                # when the file is silent or corrupt, so we log and skip.\n+                self._log.error(u'no key returned for path: {0}', item.path)\n+                continue\n+\n             try:\n                 key = util.text_string(key_raw)\n             except UnicodeDecodeError:\n", "issue": "keyfinder: Output parsing error\n### Problem\n\nRunning this command in verbose (`-vv`) mode:\n\n``` sh\n$ beet -vv keyfinder anything\n```\n\nLed to this problem:\n\n```\nuser configuration: /home/diomekes/.config/beets/config.yaml\ndata directory: /home/diomekes/.config/beets\nplugin paths:\nSending event: pluginload\ninline: adding item field disc_and_track\nlibrary database: /home/diomekes/.config/beets/library.db\nlibrary directory: /home/diomekes/media/music\nSending event: library_opened\nTraceback (most recent call last):\n  File \"/usr/bin/beet\", line 9, in <module>\n    load_entry_point('beets==1.3.19', 'console_scripts', 'beet')()\n  File \"/usr/lib/python2.7/site-packages/beets/ui/__init__.py\", line 1266, in main\n    _raw_main(args)\n  File \"/usr/lib/python2.7/site-packages/beets/ui/__init__.py\", line 1253, in _raw_main\n    subcommand.func(lib, suboptions, subargs)\n  File \"/usr/lib/python2.7/site-packages/beetsplug/keyfinder.py\", line 48, in command\n    self.find_key(lib.items(ui.decargs(args)), write=ui.should_write())\n  File \"/usr/lib/python2.7/site-packages/beetsplug/keyfinder.py\", line 74, in find_key\n    key_raw = output.rsplit(None, 1)[-1]\nIndexError: list index out of range\n```\n\nkeyfinder-cli works if run directly\n### Setup\n- OS:  archlinux\n- Python version: 2.7.12\n- beets version: 1.3.19\n- Turning off plugins made problem go away (yes/no): problem is with keyfinder plugin only\n- libkeyfinder-git 239.0a5ec7f-1\n- keyfinder-cli-git 49.40a41ab-1\n\nMy configuration (output of `beet config`) is:\n\n``` yaml\n...\nkeyfinder:\n    bin: keyfinder-cli\n    auto: yes\n    overwrite: no\n\nplugins: badfiles chroma convert duplicates fetchart fromfilename fuzzy info inline keyfinder lastgenre lyrics mbcollection mbsync missing play random scrub smartplaylist zero\n...\n```\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# This file is part of beets.\n# Copyright 2016, Thomas Scholtes.\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n\n\"\"\"Uses the `KeyFinder` program to add the `initial_key` field.\n\"\"\"\n\nfrom __future__ import division, absolute_import, print_function\n\nimport os.path\nimport subprocess\n\nfrom beets import ui\nfrom beets import util\nfrom beets.plugins import BeetsPlugin\n\n\nclass KeyFinderPlugin(BeetsPlugin):\n\n    def __init__(self):\n        super(KeyFinderPlugin, self).__init__()\n        self.config.add({\n            u'bin': u'KeyFinder',\n            u'auto': True,\n            u'overwrite': False,\n        })\n\n        if self.config['auto'].get(bool):\n            self.import_stages = [self.imported]\n\n    def commands(self):\n        cmd = ui.Subcommand('keyfinder',\n                            help=u'detect and add initial key from audio')\n        cmd.func = self.command\n        return [cmd]\n\n    def command(self, lib, opts, args):\n        self.find_key(lib.items(ui.decargs(args)), write=ui.should_write())\n\n    def imported(self, session, task):\n        self.find_key(task.imported_items())\n\n    def find_key(self, items, write=False):\n        overwrite = self.config['overwrite'].get(bool)\n        command = [self.config['bin'].as_str()]\n        # The KeyFinder GUI program needs the -f flag before the path.\n        # keyfinder-cli is similar, but just wants the path with no flag.\n        if 'keyfinder-cli' not in os.path.basename(command[0]).lower():\n            command.append('-f')\n\n        for item in items:\n            if item['initial_key'] and not overwrite:\n                continue\n\n            try:\n                output = util.command_output(command + [util.syspath(\n                                                        item.path)]).stdout\n            except (subprocess.CalledProcessError, OSError) as exc:\n                self._log.error(u'execution failed: {0}', exc)\n                continue\n            except UnicodeEncodeError:\n                # Workaround for Python 2 Windows bug.\n                # https://bugs.python.org/issue1759845\n                self._log.error(u'execution failed for Unicode path: {0!r}',\n                                item.path)\n                continue\n\n            key_raw = output.rsplit(None, 1)[-1]\n            try:\n                key = util.text_string(key_raw)\n            except UnicodeDecodeError:\n                self._log.error(u'output is invalid UTF-8')\n                continue\n\n            item['initial_key'] = key\n            self._log.info(u'added computed initial key {0} for {1}',\n                           key, util.displayable_path(item.path))\n\n            if write:\n                item.try_write()\n            item.store()\n", "path": "beetsplug/keyfinder.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# This file is part of beets.\n# Copyright 2016, Thomas Scholtes.\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n\n\"\"\"Uses the `KeyFinder` program to add the `initial_key` field.\n\"\"\"\n\nfrom __future__ import division, absolute_import, print_function\n\nimport os.path\nimport subprocess\n\nfrom beets import ui\nfrom beets import util\nfrom beets.plugins import BeetsPlugin\n\n\nclass KeyFinderPlugin(BeetsPlugin):\n\n    def __init__(self):\n        super(KeyFinderPlugin, self).__init__()\n        self.config.add({\n            u'bin': u'KeyFinder',\n            u'auto': True,\n            u'overwrite': False,\n        })\n\n        if self.config['auto'].get(bool):\n            self.import_stages = [self.imported]\n\n    def commands(self):\n        cmd = ui.Subcommand('keyfinder',\n                            help=u'detect and add initial key from audio')\n        cmd.func = self.command\n        return [cmd]\n\n    def command(self, lib, opts, args):\n        self.find_key(lib.items(ui.decargs(args)), write=ui.should_write())\n\n    def imported(self, session, task):\n        self.find_key(task.imported_items())\n\n    def find_key(self, items, write=False):\n        overwrite = self.config['overwrite'].get(bool)\n        command = [self.config['bin'].as_str()]\n        # The KeyFinder GUI program needs the -f flag before the path.\n        # keyfinder-cli is similar, but just wants the path with no flag.\n        if 'keyfinder-cli' not in os.path.basename(command[0]).lower():\n            command.append('-f')\n\n        for item in items:\n            if item['initial_key'] and not overwrite:\n                continue\n\n            try:\n                output = util.command_output(command + [util.syspath(\n                                                        item.path)]).stdout\n            except (subprocess.CalledProcessError, OSError) as exc:\n                self._log.error(u'execution failed: {0}', exc)\n                continue\n            except UnicodeEncodeError:\n                # Workaround for Python 2 Windows bug.\n                # https://bugs.python.org/issue1759845\n                self._log.error(u'execution failed for Unicode path: {0!r}',\n                                item.path)\n                continue\n\n            try:\n                key_raw = output.rsplit(None, 1)[-1]\n            except IndexError:\n                # Sometimes keyfinder-cli returns 0 but with no key, usually\n                # when the file is silent or corrupt, so we log and skip.\n                self._log.error(u'no key returned for path: {0}', item.path)\n                continue\n\n            try:\n                key = util.text_string(key_raw)\n            except UnicodeDecodeError:\n                self._log.error(u'output is invalid UTF-8')\n                continue\n\n            item['initial_key'] = key\n            self._log.info(u'added computed initial key {0} for {1}',\n                           key, util.displayable_path(item.path))\n\n            if write:\n                item.try_write()\n            item.store()\n", "path": "beetsplug/keyfinder.py"}]}