Found while measuring the icon-name population for #5633, which needed to know which resolver each authored icon string reaches. Filed unassigned; not repaired there, because it is a different defect class (no resolution at all, rather than a resolution that misses).
What happens
packages/components/src/renderers/overlay/dropdown-menu.tsx renders a menu item's icon as raw text, in both the item and the submenu-trigger arm:
// line 40 — DropdownMenuSubTrigger{item.icon&&<spanclassName="mr-2">{item.icon}</span>}// line 52 — DropdownMenuItem{item.icon&&<spanclassName="mr-2">{item.icon}</span>}item.icon is an authored string. Nothing resolves it. So the schema's own documented shape — the registration at line 99 describes items as { type?: "separator"|"label", label, icon, shortcut, disabled, children: [] } — produces the literal word beside the label.
Live specimen in the catalog: examples/schema-catalog/src/schemas/components-overlay-dropdown-menu/with-icons.json declares "icon": "edit", "copy" and "trash" on its items. The file is literally named with-icons.json, and it renders edit Edit, copy Copy, trash Delete.
Why nothing catches it
The decision this needs
Which surface the item icon should resolve through, if any:
That is a contract question, not an implementation detail, which is why this is filed rather than patched.
Generated by Claude Code
Found while measuring the icon-name population for #5633, which needed to know which resolver each authored
iconstring reaches. Filed unassigned; not repaired there, because it is a different defect class (no resolution at all, rather than a resolution that misses).What happens
packages/components/src/renderers/overlay/dropdown-menu.tsxrenders a menu item'siconas raw text, in both the item and the submenu-trigger arm:item.iconis an authored string. Nothing resolves it. So the schema's own documented shape — the registration at line 99 describes items as{ type?: "separator"|"label", label, icon, shortcut, disabled, children: [] }— produces the literal word beside the label.Live specimen in the catalog:
examples/schema-catalog/src/schemas/components-overlay-dropdown-menu/with-icons.jsondeclares"icon": "edit","copy"and"trash"on its items. The file is literally namedwith-icons.json, and it rendersedit Edit,copy Copy,trash Delete.Why nothing catches it
iconis part of the declared item shape.icon:literal reaching a record-reading lucide resolver is a liveiconskey — four hand-copied resolvers, four local pins, no gate over the population #5633 gate by design: that gate judges membership of lucide's runtimeiconsrecord for names that reach a resolver reading it, and this site reaches no resolver. Its verdict on these three names is "declined", which is the right answer to the question it asks and the wrong shape of silence for this defect.The decision this needs
Which surface the item icon should resolve through, if any:
resolveIconfromrenderers/action/resolve-icon.ts) — consistent withaction:*andui:buttonnext to it; a retired spelling renders nothing.LazyIcon/getLazyIcon) — more forgiving, but it degrades an unknown name to theDatabaseglyph, which trades a no-icon failure for a wrong-icon one. Two more retired lucide spellings reach theicons-record resolver —editin DetailView's mobile Edit action,smileas theiconrenderer's own default — and only one of the four resolver copies is pinned #5622 and Nothing checks that anicon:literal reaching a record-reading lucide resolver is a liveiconskey — four hand-copied resolvers, four local pins, no gate over the population #5633 both recorded that as ruled out for authored icon fields.iconis not a real authored key on this component and should be retired from the declared item shape and the fixture instead.That is a contract question, not an implementation detail, which is why this is filed rather than patched.
Generated by Claude Code