You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Bug: Tag taxonomy term picker shows no existing terms when taxonomy is added to a custom collection #1199
When enabling the built-in tag taxonomy for a custom collection (not posts), the term picker in the admin editor shows no existing terms — only a "create new" prompt. This makes it impossible to assign pre-existing tags to entries in that collection.
What I was trying to do:
I wanted to use tags to control which projects appear in different page sections (homepage slider, regional landing pages). The plan was:
Add the projects collection to the tag taxonomy's collections array
Create tag terms like homepage and moskva
Assign them to project entries via the admin
What happened:
Updated _emdash_taxonomy_defs via SQL: collections = '[\"posts\",\"projects\"]'
Created terms via SQL with correct translation_group = id
The Tags widget appeared in the project editor ✓
Clicking the tag picker opened an empty picker with only a "create" prompt — existing terms never appeared ✗
After restarting the dev server, same result
Tried both with translation_group = NULL (first attempt) and translation_group = id (second attempt, matching TaxonomyRepository.create() pattern) — no difference in picker behavior.
Root issue: There appears to be no supported way to enable the tag (or category) taxonomy for a custom collection. The collections field on _emdash_taxonomy_defs implies it should work, but the admin term picker does not surface existing terms for non-posts collections even when the data is correctly structured in the database.
Steps to reproduce
Create a custom collection (e.g. projects) via npx emdash schema create
Manually update the tag taxonomy to include the new collection:
UPDATE _emdash_taxonomy_defs SET collections ='["posts","projects"]'WHERE name ='tag';
Click the Tags field — the term picker opens but shows no existing terms, only a "create" prompt
Expected behavior
The tag term picker should display existing terms (Homepage, etc.) as selectable options
Alternatively: there should be an official CLI command or admin UI to add a taxonomy to a custom collection (e.g. npx emdash schema add-taxonomy projects tag)
Root cause (medium confidence): packages/admin/src/components/TaxonomySidebar.tsx:170-176 (the TagInputsuggestions memo, plus the related showCreateOption on line 183). For non-hierarchical taxonomies (tag), the picker is a free-text autocomplete: suggestions short-circuits to [] when trimmedInput is empty, and the suggestions dropdown is rendered only when suggestions.length > 0 || showCreateOption. So clicking the Tags field with no text typed produces an empty, invisible picker — there is no list of existing terms and no affordance to discover them. The hierarchical branch in the same file (TaxonomySection, around lines 393–417) renders the full term list up-front, which is why categories appear and tags do not. This produces exactly the symptom reported: "the term picker opens but shows no existing terms, only a create prompt" — they only ever see Create after they start typing, because before typing the dropdown is hidden, and after typing a non-matching prefix only the Create row appears. Whether the taxonomy is attached to posts or to a custom collection is irrelevant; this is a UI affordance defect in the flat (tag-style) picker, not a data/collections-filtering bug. (Server side confirms: handleTermList in packages/core/src/api/handlers/taxonomies.ts:360 doesn't filter terms by collection, and findByName in packages/core/src/database/repositories/taxonomy.ts:128 doesn't either; reproduce verified the API returns the inserted term immediately.) Hypotheses considered: Confidence is medium, not high, because the right fix is a design decision rather than a one-line mechanical change. Plausible fixes: (a) render the suggestions dropdown unconditionally on focus and show the first N existing terms when input is empty; (b) keep typing-triggered behaviour but add helper text under the input like "X existing tags — type to filter"; (c) switch the tag picker to a combobox/listbox like the category checkbox tree. A maintainer should pick one. \n\nSecondary contributors that explain why the reporter described it as a complete failure: (1) the React Query cache in TaxonomySidebar (queryKey: ["taxonomy-terms", taxonomy.name]) is not invalidated when terms are inserted out-of-band via raw SQL — only createTermMutation.onSuccess invalidates it. The reporter inserted via SQL, never refreshed, and React Query served a cached empty list. Reproduce confirmed a hard reload fixes that. This is arguably working-as-designed (SQL bypasses the app), but it compounds the UX defect: even after typing, a stale cache yields no suggestion and only the Create row. (2) The reporter's other plausible alternative root cause — that collections filtering hides terms for non-posts collections — was ruled out at reproduce time: typing "w" surfaces "Web Development" once the page is fresh, and the /taxonomies/:name/terms endpoint has no collection filter.\n\nNot considered the cause: server-side cache (invalidateTermCache is a documented no-op), locale filtering (admin requests without ?locale return all locales, and the seeded + inserted terms all use 'en'), or permissions (request returns 200 with terms). Verdict:bug — The behaviour in packages/admin/src/components/TaxonomySidebar.tsx:170-185 makes existing tag terms undiscoverable from the picker UI. There is no docstring, no inline comment, no doc page, and no test that asserts "the tag picker intentionally renders nothing until the user types" — the only mock of this component (packages/admin/tests/components/ContentEditor.test.tsx:63-64) replaces it wholesale, asserting nothing about its interactive behaviour. The sibling hierarchical branch in the same file (TaxonomySection, ~lines 393–417) renders every term up front for categories, which is direct internal evidence that the intent is "show what already exists"; the flat branch silently diverges from that intent. The reporter's expectation that clicking the Tags field should reveal existing tags is reasonable and matches the categories UX in the same component. So the behaviour matches the code but the code does not match documented or implied intent: bug.\n\nThat said, the diagnose's medium-confidence call is correct — the fix is a UX design choice (show top N on focus vs. always-open listbox vs. helper text). Per the verify gate, this will not auto-trigger the fix stage; the orchestrator should comment with the diagnosis and let a maintainer pick the resolution shape. The reporter's secondary "no supported way to attach taxonomies to custom collections" claim is separately not a bug — reproduce confirmed the SQL-level mechanism works and the server returns the terms — but the picker UX defect is real.
The bot reproduced the bug but did not attempt a fix. The fix stage requires verdict: bug AND confidence: high.
Opened a PR. The tag picker now shows existing terms on focus (not only while typing), with focus/blur open-state handling and a mousedown guard so clicks register before blur closes the list.
Activity
emdashbot commentedon May 29, 2026
The investigation bot reproduced this issue.
Root cause (
mediumconfidence): packages/admin/src/components/TaxonomySidebar.tsx:170-176 (theTagInputsuggestionsmemo, plus the relatedshowCreateOptionon line 183). For non-hierarchical taxonomies (tag), the picker is a free-text autocomplete:suggestionsshort-circuits to[]whentrimmedInputis empty, and the suggestions dropdown is rendered only whensuggestions.length > 0 || showCreateOption. So clicking the Tags field with no text typed produces an empty, invisible picker — there is no list of existing terms and no affordance to discover them. The hierarchical branch in the same file (TaxonomySection, around lines 393–417) renders the full term list up-front, which is why categories appear and tags do not. This produces exactly the symptom reported: "the term picker opens but shows no existing terms, only a create prompt" — they only ever see Create after they start typing, because before typing the dropdown is hidden, and after typing a non-matching prefix only the Create row appears. Whether the taxonomy is attached topostsor to a custom collection is irrelevant; this is a UI affordance defect in the flat (tag-style) picker, not a data/collections-filtering bug. (Server side confirms:handleTermListin packages/core/src/api/handlers/taxonomies.ts:360 doesn't filter terms by collection, andfindByNamein packages/core/src/database/repositories/taxonomy.ts:128 doesn't either; reproduce verified the API returns the inserted term immediately.)Hypotheses considered: Confidence is medium, not high, because the right fix is a design decision rather than a one-line mechanical change. Plausible fixes: (a) render the suggestions dropdown unconditionally on focus and show the first N existing terms when input is empty; (b) keep typing-triggered behaviour but add helper text under the input like "X existing tags — type to filter"; (c) switch the tag picker to a combobox/listbox like the category checkbox tree. A maintainer should pick one. \n\nSecondary contributors that explain why the reporter described it as a complete failure: (1) the React Query cache in TaxonomySidebar (
queryKey: ["taxonomy-terms", taxonomy.name]) is not invalidated when terms are inserted out-of-band via raw SQL — onlycreateTermMutation.onSuccessinvalidates it. The reporter inserted via SQL, never refreshed, and React Query served a cached empty list. Reproduce confirmed a hard reload fixes that. This is arguably working-as-designed (SQL bypasses the app), but it compounds the UX defect: even after typing, a stale cache yields no suggestion and only the Create row. (2) The reporter's other plausible alternative root cause — thatcollectionsfiltering hides terms for non-postscollections — was ruled out at reproduce time: typing "w" surfaces "Web Development" once the page is fresh, and the/taxonomies/:name/termsendpoint has no collection filter.\n\nNot considered the cause: server-side cache (invalidateTermCache is a documented no-op), locale filtering (admin requests without ?locale return all locales, and the seeded + inserted terms all use 'en'), or permissions (request returns 200 with terms).Verdict:
bug— The behaviour in packages/admin/src/components/TaxonomySidebar.tsx:170-185 makes existing tag terms undiscoverable from the picker UI. There is no docstring, no inline comment, no doc page, and no test that asserts "the tag picker intentionally renders nothing until the user types" — the only mock of this component (packages/admin/tests/components/ContentEditor.test.tsx:63-64) replaces it wholesale, asserting nothing about its interactive behaviour. The sibling hierarchical branch in the same file (TaxonomySection, ~lines 393–417) renders every term up front for categories, which is direct internal evidence that the intent is "show what already exists"; the flat branch silently diverges from that intent. The reporter's expectation that clicking the Tags field should reveal existing tags is reasonable and matches the categories UX in the same component. So the behaviour matches the code but the code does not match documented or implied intent: bug.\n\nThat said, the diagnose's medium-confidence call is correct — the fix is a UX design choice (show top N on focus vs. always-open listbox vs. helper text). Per the verify gate, this will not auto-trigger the fix stage; the orchestrator should comment with the diagnosis and let a maintainer pick the resolution shape. The reporter's secondary "no supported way to attach taxonomies to custom collections" claim is separately not a bug — reproduce confirmed the SQL-level mechanism works and the server returns the terms — but the picker UX defect is real.The bot reproduced the bug but did not attempt a fix. The fix stage requires
verdict: bugANDconfidence: high.A maintainer will pick up the fix from here.
Run: https://github.com/emdash-cms/emdash/actions/runs/26635970483
mvanhorn commentedon May 31, 2026
Opened a PR. The tag picker now shows existing terms on focus (not only while typing), with focus/blur open-state handling and a mousedown guard so clicks register before blur closes the list.
TaxonomySidebar: show existing taxonomy terms in the tag picker (emda…
Investigate-bot fix gate, preview self-consistency, and bot identity …