diff --git a/server/szurubooru/search/base_search_config.py b/server/szurubooru/search/base_search_config.py
index 6df7eb55..9b4d06f0 100644
--- a/server/szurubooru/search/base_search_config.py
+++ b/server/szurubooru/search/base_search_config.py
@@ -38,22 +38,26 @@ class BaseSearchConfig(object):
         '''
         Decorate SQLAlchemy filter on given column using supplied criterion.
         '''
-        if isinstance(criterion, criteria.PlainSearchCriterion):
-            expr = column == int(criterion.value)
-        elif isinstance(criterion, criteria.ArraySearchCriterion):
-            expr = column.in_(int(value) for value in criterion.values)
-        elif isinstance(criterion, criteria.RangedSearchCriterion):
-            assert criterion.min_value != '' \
-                or criterion.max_value != ''
-            if criterion.min_value != '' and criterion.max_value != '':
-                expr = column.between(
-                    int(criterion.min_value), int(criterion.max_value))
-            elif criterion.min_value != '':
-                expr = column >= int(criterion.min_value)
-            elif criterion.max_value != '':
-                expr = column <= int(criterion.max_value)
-        else:
-            assert False
+        try:
+            if isinstance(criterion, criteria.PlainSearchCriterion):
+                expr = column == int(criterion.value)
+            elif isinstance(criterion, criteria.ArraySearchCriterion):
+                expr = column.in_(int(value) for value in criterion.values)
+            elif isinstance(criterion, criteria.RangedSearchCriterion):
+                assert criterion.min_value != '' \
+                    or criterion.max_value != ''
+                if criterion.min_value != '' and criterion.max_value != '':
+                    expr = column.between(
+                        int(criterion.min_value), int(criterion.max_value))
+                elif criterion.min_value != '':
+                    expr = column >= int(criterion.min_value)
+                elif criterion.max_value != '':
+                    expr = column <= int(criterion.max_value)
+            else:
+                assert False
+        except ValueError as e:
+            raise errors.SearchError(
+                'Criterion value %r must be a number.' % (criterion,))
         if criterion.negated:
             expr = ~expr
         return expr
diff --git a/server/szurubooru/tests/search/test_tag_search_config.py b/server/szurubooru/tests/search/test_tag_search_config.py
index a3c48992..7582a57f 100644
--- a/server/szurubooru/tests/search/test_tag_search_config.py
+++ b/server/szurubooru/tests/search/test_tag_search_config.py
@@ -134,7 +134,9 @@ def test_filter_by_edit_time(
     ('post-count:2', ['t1']),
     ('post-count:1', ['t2']),
     ('post-count:1..', ['t1', 't2']),
+    ('post-count-min:1', ['t1', 't2']),
     ('post-count:..1', ['t2']),
+    ('post-count-max:1', ['t2']),
     ('usage-count:2', ['t1']),
     ('usage-count:1', ['t2']),
     ('usages:2', ['t1']),
@@ -153,6 +155,19 @@ def test_filter_by_post_count(
     post2.tags.append(tag1)
     verify_unpaged(input, expected_tag_names)
 
+@pytest.mark.parametrize('input', [
+    'post-count:..',
+    'post-count:asd',
+    'post-count:asd,1',
+    'post-count:1,asd',
+    'post-count:asd..1',
+    'post-count:1..asd',
+])
+def test_filter_by_invalid_input(executor, input):
+    with pytest.raises(errors.SearchError):
+        actual_count, actual_posts = executor.execute(
+            input, page=1, page_size=100)
+
 @pytest.mark.parametrize('input,expected_tag_names', [
     ('suggestion-count:2', ['t1']),
     ('suggestion-count:1', ['t2']),