# Buggy code
def search(self, search_strings, age=0, ep_obj=None, **kwargs):
    """
    Search a provider and parse the results.

    :param search_strings: A dict with mode (key) and the search value (value)
    :param age: Not used
    :param ep_obj: Not used
    :returns: A list of search results (structure)
    """
    results = []
    if not self.login():
        return results

    for mode in search_strings:
        log.debug("Search mode: {0}", mode)

        for search_string in search_strings[mode]:
            if mode != "RSS":
                log.debug("Search string: {search}", {"search": search_string})

            search_string = "+".join(search_string.split())

            params = dict({"q": search_string}, **self.categories[mode])

            response = self.session.get(self.urls["search"], params=params)
            if not response or not response.content:
                log.debug("No data returned from provider")
                continue

            try:
                jdata = djson.loads(response.content)
            except ValueError as error:
                log.error("Couldn't deserialize JSON document. Error: {0!r}", error)
                continue

            results += self.parse(jdata, mode)

    return results


# Traceback (AttributeError)
2019-03-15 05:03:02 ERROR    TORNADO :: [94fae84] API :: AttributeError("'str' object has no attribute 'decode'")
Traceback (most recent call last):
File "/Users/matt/Builds/medusa/medusa/server/api/v1/core.py", line 142, in get
out_dict = _call_dispatcher(args, kwargs)
File "/Users/matt/Builds/medusa/medusa/server/api/v1/core.py", line 212, in call_dispatcher
cur_out_dict = func(cur_args, cur_kwargs).run()  # call function and get response
File "/Users/matt/Builds/medusa/medusa/server/api/v1/core.py", line 1308, in run
failed=self.failed, proc_type=self.type
File "/Users/matt/Builds/medusa/medusa/process_tv.py", line 145, in process
ignore_subs=ignore_subs)
File "/Users/matt/Builds/medusa/medusa/process_tv.py", line 335, in process_files
self.process_media(path, self.video_files, force, is_priority, ignore_subs)
File "/Users/matt/Builds/medusa/medusa/process_tv.py", line 556, in process_media
self.result = processor.process()
File "/Users/matt/Builds/medusa/medusa/post_processor.py", line 1289, in process
notifiers.notify_download(ep_obj)
File "/Users/matt/Builds/medusa/medusa/notifiers/__init__.py", line 100, in notify_download
n.notify_download(ep_obj)
File "/Users/matt/Builds/medusa/medusa/notifiers/kodi.py", line 434, in notify_download
self._notify_kodi(common.notifyStrings[common.NOTIFY_DOWNLOAD], ep_obj.pretty_name_with_quality())
File "/Users/matt/Builds/medusa/medusa/notifiers/kodi.py", line 133, in _notify_kodi
result += cur_host + ':' + notify_result['result'].decode('utf-8')
AttributeError: 'str' object has no attribute 'decode'
2019-03-15 05:03:02 INFO     TORNADO :: [94fae84] Selected poster for series 275557 (score=3.3221824253021945, score_bay=5.644364850604389, rating=6.8, votes=20, res=680x1000): https://www.thetvdb.com/banners/posters/275557-6.jpg
2019-03-15 05:03:02 INFO     TORNADO :: [94fae84] Selected fanart for series 275557 (score=3.9240400637751476, score_bay=5.848080127550295, rating=6.9, votes=9, res=1920x1080): https://www.thetvdb.com/banners/fanart/original/275557-8.jpg
2019-03-15 05:03:00 INFO     TORNADO :: [94fae84] 275557: Changed modify date of Broad.City.S05E08.Sleep.No.More.720p.WEB-DL.mkv to series air date Mar 14,2019 (22:00)
2019-03-15 05:02:46 INFO     TORNADO :: [94fae84] Release name (broad.city.s05e08.720p.web.x264-tbs) found from file (broad.city.s05e08.720p.web.x264-tbs.nfo)
2019-03-15 05:02:46 INFO     TORNADO :: [94fae84] This download is marked a priority download so I'm going to replace an existing file if I find one
2019-03-15 05:02:46 INFO     TORNADO :: [94fae84] New size: 432.58 MB
2019-03-15 05:02:46 INFO     TORNADO :: [94fae84] New file: /Volumes/dvorak.8tb/SABnzbd/tv/Broad.City.S05E08.720p.WEB.x264-TBS[TGx]/broad.city.s05e08.720p.web.x264-tbs.mkv
2019-03-15 05:02:46 INFO     TORNADO :: [94fae84] Processing /Volumes/dvorak.8tb/SABnzbd/tv/Broad.City.S05E08.720p.WEB.x264-TBS[TGx]/broad.city.s05e08.720p.web.x264-tbs.mkv

# Fixed code
def search(self, search_strings, age=0, ep_obj=None, **kwargs):
    """
    Search a provider and parse the results.

    :param search_strings: A dict with mode (key) and the search value (value)
    :param age: Not used
    :param ep_obj: Not used
    :returns: A list of search results (structure)
    """
    results = []
    if not self.login():
        return results

    for mode in search_strings:
        log.debug("Search mode: {0}", mode)

        for search_string in search_strings[mode]:
            if mode != "RSS":
                log.debug("Search string: {search}", {"search": search_string})

            search_string = "+".join(search_string.split())

            params = dict({"q": search_string}, **self.categories[mode])

            response = self.session.get(self.urls["search"], params=params)
            if not response or not response.text:
                log.debug("No data returned from provider")
                continue

            try:
                jdata = djson.loads(response.text)
            except ValueError as error:
                log.error("Couldn't deserialize JSON document. Error: {0!r}", error)
                continue

            results += self.parse(jdata, mode)

    return results