diff --git a/modules/restapi/src/main/resources/docspell-openapi.yml b/modules/restapi/src/main/resources/docspell-openapi.yml
index e113496d..59dc743f 100644
--- a/modules/restapi/src/main/resources/docspell-openapi.yml
+++ b/modules/restapi/src/main/resources/docspell-openapi.yml
@@ -4382,7 +4382,6 @@ components:
       description: |
         Generic structure for counting something.
       required:
-        - name
         - count
       properties:
         name:
diff --git a/modules/store/src/main/scala/docspell/store/queries/CategoryCount.scala b/modules/store/src/main/scala/docspell/store/queries/CategoryCount.scala
index fd502037..9724b1c6 100644
--- a/modules/store/src/main/scala/docspell/store/queries/CategoryCount.scala
+++ b/modules/store/src/main/scala/docspell/store/queries/CategoryCount.scala
@@ -1,3 +1,3 @@
 package docspell.store.queries
 
-final case class CategoryCount(category: String, count: Int)
+final case class CategoryCount(category: Option[String], count: Int)
diff --git a/modules/store/src/main/scala/docspell/store/queries/QItem.scala b/modules/store/src/main/scala/docspell/store/queries/QItem.scala
index b9335055..f9c0af38 100644
--- a/modules/store/src/main/scala/docspell/store/queries/QItem.scala
+++ b/modules/store/src/main/scala/docspell/store/queries/QItem.scala
@@ -203,7 +203,7 @@ object QItem {
         .innerJoin(tag, tag.tid === ti.tagId)
         .innerJoin(i, i.id === ti.itemId)
 
-    val tagCloud =
+    val catCloud =
       findItemsBase(q.fix, today, 0).unwrap
         .withSelect(select(tag.category).append(countDistinct(i.id).as("num")))
         .changeFrom(_.prepend(tagFrom))
@@ -213,14 +213,11 @@ object QItem {
         .query[CategoryCount]
         .to[List]
 
-    // the previous query starts from tags, so items with tag-count=0
-    // are not included they are fetched separately
     for {
-      existing <- tagCloud
+      existing <- catCloud
       allCats  <- RTag.listCategories(q.fix.account.collective)
-      other = allCats.diff(existing.map(_.category))
-    } yield existing ++ other.map(CategoryCount(_, 0))
-
+      other = allCats.diff(existing.flatMap(_.category))
+    } yield existing ++ other.map(n => CategoryCount(n.some, 0))
   }
 
   def searchTagSummary(today: LocalDate)(q: Query): ConnectionIO[List[TagCount]] = {
diff --git a/modules/webapp/src/main/elm/Comp/TagSelect.elm b/modules/webapp/src/main/elm/Comp/TagSelect.elm
index 31fa8cda..2ace84cc 100644
--- a/modules/webapp/src/main/elm/Comp/TagSelect.elm
+++ b/modules/webapp/src/main/elm/Comp/TagSelect.elm
@@ -1,5 +1,6 @@
 module Comp.TagSelect exposing
-    ( Model
+    ( CategoryCount
+    , Model
     , Msg
     , Selection
     , WorkModel
@@ -38,9 +39,9 @@ import Util.Maybe
 
 type alias Model =
     { availableTags : Dict String TagCount
-    , availableCats : Dict String NameCount
+    , availableCats : Dict String CategoryCount
     , tagCounts : List TagCount
-    , categoryCounts : List NameCount
+    , categoryCounts : List CategoryCount
     , filterTerm : Maybe String
     , expandedTags : Bool
     , expandedCats : Bool
@@ -48,16 +49,22 @@ type alias Model =
     }
 
 
+type alias CategoryCount =
+    { name : String
+    , count : Int
+    }
+
+
 init : List TagCount -> List NameCount -> List TagCount -> List NameCount -> Model
 init allTags allCats tags cats =
     { availableTags =
         List.map (\e -> ( e.tag.id, e )) allTags
             |> Dict.fromList
     , availableCats =
-        List.map (\e -> ( e.name, e )) allCats
+        List.filterMap (\e -> Maybe.map (\k -> ( k, CategoryCount k e.count )) e.name) allCats
             |> Dict.fromList
     , tagCounts = tags
-    , categoryCounts = cats
+    , categoryCounts = List.filterMap (\e -> Maybe.map (\k -> CategoryCount k e.count) e.name) cats
     , filterTerm = Nothing
     , expandedTags = False
     , expandedCats = False
@@ -72,7 +79,7 @@ modifyAll allTags allCats model =
             List.map (\e -> ( e.tag.id, e )) allTags
                 |> Dict.fromList
         , availableCats =
-            List.map (\e -> ( e.name, e )) allCats
+            List.filterMap (\e -> Maybe.map (\k -> ( k, CategoryCount k e.count )) e.name) allCats
                 |> Dict.fromList
     }
 
@@ -81,7 +88,7 @@ modifyCount : Model -> List TagCount -> List NameCount -> Model
 modifyCount model tags cats =
     { model
         | tagCounts = tags
-        , categoryCounts = cats
+        , categoryCounts = List.filterMap (\e -> Maybe.map (\k -> CategoryCount k e.count) e.name) cats
     }
 
 
@@ -103,8 +110,8 @@ toggleTag id =
 type alias Selection =
     { includeTags : List TagCount
     , excludeTags : List TagCount
-    , includeCats : List NameCount
-    , excludeCats : List NameCount
+    , includeCats : List CategoryCount
+    , excludeCats : List CategoryCount
     }
 
 
@@ -114,7 +121,7 @@ emptySelection =
 
 
 type alias WorkModel =
-    { filteredCats : List NameCount
+    { filteredCats : List CategoryCount
     , filteredTags : List TagCount
     , selectedTags : Dict String Bool
     , selectedCats : Dict String Bool
@@ -135,7 +142,7 @@ orderTagCountStable model tagCounts =
     List.sortBy order tagCounts
 
 
-orderCatCountStable : Model -> List NameCount -> List NameCount
+orderCatCountStable : Model -> List CategoryCount -> List CategoryCount
 orderCatCountStable model catCounts =
     let
         order cat =
@@ -162,7 +169,7 @@ removeEmptyTagCounts sel tagCounts =
     List.filter (\tc -> isSelected tc || tc.count > 0) tagCounts
 
 
-removeEmptyCatCounts : Selection -> List NameCount -> List NameCount
+removeEmptyCatCounts : Selection -> List CategoryCount -> List CategoryCount
 removeEmptyCatCounts sel catCounts =
     let
         selected =
@@ -517,7 +524,7 @@ viewTagItem2 ddm settings model tag =
         ]
 
 
-viewCategoryItem2 : UiSettings -> WorkModel -> NameCount -> Html Msg
+viewCategoryItem2 : UiSettings -> WorkModel -> CategoryCount -> Html Msg
 viewCategoryItem2 settings model cat =
     let
         state =