diff --git a/api/funkwhale_api/music/admin.py b/api/funkwhale_api/music/admin.py
index 219b40a91deeeb9d06dd55d3292aa5ca22ccc654..667a7c2a1b10659c4d608fa2af5b6bcaf04e2681 100644
--- a/api/funkwhale_api/music/admin.py
+++ b/api/funkwhale_api/music/admin.py
@@ -38,6 +38,7 @@ class ImportBatchAdmin(admin.ModelAdmin):
     search_fields = [
         'import_request__name', 'source', 'batch__pk', 'mbid']
 
+
 @admin.register(models.ImportJob)
 class ImportJobAdmin(admin.ModelAdmin):
     list_display = ['source', 'batch', 'track_file', 'status', 'mbid']
@@ -77,5 +78,10 @@ class TrackFileAdmin(admin.ModelAdmin):
     list_select_related = [
         'track'
     ]
-    search_fields = ['source', 'acoustid_track_id']
+    search_fields = [
+        'source',
+        'acoustid_track_id',
+        'track__title',
+        'track__album__title',
+        'track__artist__name']
     list_filter = ['mimetype']
diff --git a/api/funkwhale_api/subsonic/renderers.py b/api/funkwhale_api/subsonic/renderers.py
index 74cf13d887d9186a1bd50b4569fe59970daff762..3a56645012f07910a9c0e175b3b3e3d6f6bec8f2 100644
--- a/api/funkwhale_api/subsonic/renderers.py
+++ b/api/funkwhale_api/subsonic/renderers.py
@@ -15,6 +15,9 @@ class SubsonicJSONRenderer(renderers.JSONRenderer):
             }
         }
         final['subsonic-response'].update(data)
+        if 'error' in final:
+            # an error was returned
+            final['subsonic-response']['status'] = 'failed'
         return super().render(final, accepted_media_type, renderer_context)
 
 
@@ -31,6 +34,9 @@ class SubsonicXMLRenderer(renderers.JSONRenderer):
             'version': '1.16.0',
         }
         final.update(data)
+        if 'error' in final:
+            # an error was returned
+            final['status'] = 'failed'
         tree = dict_to_xml_tree('subsonic-response', final)
         return b'<?xml version="1.0" encoding="UTF-8"?>\n' + ET.tostring(tree, encoding='utf-8')
 
diff --git a/api/funkwhale_api/subsonic/views.py b/api/funkwhale_api/subsonic/views.py
index 475e61aa73119ff8df9a71fa2a27cf3188dc0cff..2692a3dda804ad22c07ee340012ad037afb5e42b 100644
--- a/api/funkwhale_api/subsonic/views.py
+++ b/api/funkwhale_api/subsonic/views.py
@@ -31,15 +31,19 @@ def find_object(queryset, model_field='pk', field='id', cast=int):
                 raw_value = data[field]
             except KeyError:
                 return response.Response({
-                    'code': 10,
-                    'message': "required parameter '{}' not present".format(field)
+                    'error': {
+                        'code': 10,
+                        'message': "required parameter '{}' not present".format(field)
+                    }
                 })
             try:
                 value = cast(raw_value)
             except (TypeError, ValidationError):
                 return response.Response({
-                    'code': 0,
-                    'message': 'For input string "{}"'.format(raw_value)
+                    'error': {
+                        'code': 0,
+                        'message': 'For input string "{}"'.format(raw_value)
+                    }
                 })
             qs = queryset
             if hasattr(qs, '__call__'):
@@ -48,9 +52,11 @@ def find_object(queryset, model_field='pk', field='id', cast=int):
                 obj = qs.get(**{model_field: value})
             except qs.model.DoesNotExist:
                 return response.Response({
-                    'code': 70,
-                    'message': '{} not found'.format(
-                        qs.model.__class__.__name__)
+                    'error': {
+                        'code': 70,
+                        'message': '{} not found'.format(
+                            qs.model.__class__.__name__)
+                    }
                 })
             kwargs['obj'] = obj
             return func(self, request, *args, **kwargs)
@@ -83,15 +89,14 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         payload = {
             'status': 'failed'
         }
-        try:
+        if exc.__class__ in mapping:
             code, message = mapping[exc.__class__]
-        except KeyError:
-            return super().handle_exception(exc)
         else:
-            payload['error'] = {
-                'code': code,
-                'message': message
-            }
+            return super().handle_exception(exc)
+        payload['error'] = {
+            'code': code,
+            'message': message
+        }
 
         return response.Response(payload, status=200)
 
@@ -450,8 +455,10 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         name = data.get('name', '')
         if not name:
             return response.Response({
-                'code': 10,
-                'message': 'Playlist ID or name must be specified.'
+                'error': {
+                    'code': 10,
+                    'message': 'Playlist ID or name must be specified.'
+                }
             }, data)
 
         playlist = request.user.playlists.create(
diff --git a/changes/changelog.d/199.bugfix b/changes/changelog.d/199.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..0dff4f9fe4d8efb07d58ffb10580b334f2fdff86
--- /dev/null
+++ b/changes/changelog.d/199.bugfix
@@ -0,0 +1 @@
+Uplayable tracks are now properly disabled in the interface (#199)
diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue
index 2662f30b33a5321a1e2d0121c3930c46b5f66097..efa59a29d5c65fe30b88aedc5f453b8e9a250a61 100644
--- a/front/src/components/audio/PlayButton.vue
+++ b/front/src/components/audio/PlayButton.vue
@@ -1,8 +1,9 @@
 <template>
-  <div :class="['ui', {'tiny': discrete}, 'buttons']">
+  <div :title="title" :class="['ui', {'tiny': discrete}, 'buttons']">
     <button
       :title="$t('Add to current queue')"
       @click="addNext(true)"
+      :disabled="!playable"
       :class="['ui', {loading: isLoading}, {'mini': discrete}, {disabled: !playable}, 'button']">
       <i class="ui play icon"></i>
       <template v-if="!discrete"><slot><i18next path="Play"/></slot></template>
@@ -10,9 +11,9 @@
     <div v-if="!discrete" :class="['ui', {disabled: !playable}, 'floating', 'dropdown', 'icon', 'button']">
       <i class="dropdown icon"></i>
       <div class="menu">
-        <div class="item"@click="add"><i class="plus icon"></i><i18next path="Add to queue"/></div>
-        <div class="item"@click="addNext()"><i class="step forward icon"></i><i18next path="Play next"/></div>
-        <div class="item"@click="addNext(true)"><i class="arrow down icon"></i><i18next path="Play now"/></div>
+        <div class="item" :disabled="!playable" @click="add"><i class="plus icon"></i><i18next path="Add to queue"/></div>
+        <div class="item" :disabled="!playable" @click="addNext()"><i class="step forward icon"></i><i18next path="Play next"/></div>
+        <div class="item" :disabled="!playable" @click="addNext(true)"><i class="arrow down icon"></i><i18next path="Play now"/></div>
       </div>
     </div>
   </div>
@@ -45,9 +46,18 @@ export default {
     jQuery(this.$el).find('.ui.dropdown').dropdown()
   },
   computed: {
+    title () {
+      if (this.playable) {
+        return this.$t('Play immediatly')
+      } else {
+        if (this.track) {
+          return this.$t('This track is not imported and cannot be played')
+        }
+      }
+    },
     playable () {
       if (this.track) {
-        return true
+        return this.track.files.length > 0
       } else if (this.tracks) {
         return this.tracks.length > 0
       } else if (this.playlist) {