spree/spree · error · Error
Slot entry "${name}#${id}" not found.
Error message
Slot entry "${name}#${id}" not found. What it means
Thrown by updateSlot(name, id, patch) in @spree/dashboard-core when the slot registry has no entry with that id in the named slot — either the slot name is unknown or the id was never registered (registerSlot creates entries; updateSlot only patches). The message identifies the entry as "name#id" so you can see which half of the pair failed.
Source
Thrown at packages/dashboard-core/src/lib/slot-registry.ts:85
export function removeSlot(name: string, id: string): void {
const list = registry.get(name)
if (!list) return
const next = list.filter((e) => e.id !== id)
if (next.length === list.length) return
registry.set(name, next)
notify()
}
export function updateSlot<TContext = unknown>(
name: string,
id: string,
patch: Partial<Omit<SlotEntry<TContext>, 'id'>>,
): void {
const list = registry.get(name)
const entry = list?.find((e) => e.id === id)
if (!list || !entry) {
throw new Error(`Slot entry "${name}#${id}" not found.`)
}
registry.set(
name,
list.map((e) => (e.id === id ? ({ ...e, ...patch } as SlotEntry) : e)),
)
notify()
}
/**
* Subscribe to a slot's entries. Re-renders when entries are added/removed/updated
* so plugins registered after first render still appear.
*
* Returned entries are sorted by position (default 100) and stable within ties.
* Filtering by `if` happens at render time inside <Slot> — the hook returns the
* full registered list so the caller can decide how to combine context.
*/
export function useSlotEntries(name: string): readonly SlotEntry[] {
const entries = useSyncExternalStore(View on GitHub (pinned to 06bf66a868)
Solutions
- Verify the slot name and id exactly match the registerSlot call (built-ins are declared in the dashboard shell — check its source for the canonical name)
- Track the ids you registered and only update those
- Use an upsert helper: catch not-found and fall back to registerSlot with a full entry
- Export shared constants for slot names from one module instead of repeating string literals
Example fix
// before
updateSlot('product.form-sidebar', 'acme.wishlist-count', { position: 10 }) // slot name typo
// after
updateSlot('product.form_sidebar', 'acme.wishlist-count', { position: 10 })
// upsert if the entry may not exist yet
try {
updateSlot('product.form_sidebar', 'acme.wishlist-count', patch)
} catch (err) {
if (!(err instanceof Error && err.message.includes('not found'))) throw err
registerSlot('product.form_sidebar', { id: 'acme.wishlist-count', component: WishlistCount, ...patch })
} Defensive patterns
Strategy: validation
Validate before calling
// Track your own slot ids; never updateSlot a pair you did not register.
import { registerSlot, updateSlot } from '@spree/dashboard-core'
const mySlotIds = new Set<string>()
export function registerMySlot(name: string, entry: SlotEntry): void {
registerSlot(name, entry)
mySlotIds.add(`${name}#${entry.id}`)
}
export function updateMySlot(name: string, id: string, patch: Partial<SlotEntry>): void {
if (!mySlotIds.has(`${name}#${id}`)) return
updateSlot(name, id, patch)
} Try / catch
// Upsert: register the full entry when the patch target is missing.
try {
updateSlot(name, id, patch)
} catch (err) {
if (!(err instanceof Error && err.message.includes('not found'))) throw err
registerSlot(name, { id, component: FallbackComponent, ...patch } as SlotEntry)
} Prevention
- Export slot-name constants from a shared module instead of repeating literals
- Verify built-in slot names/ids against the dashboard shell source before patching
- Remember the registry key is the pair name#id — a correct id with a wrong slot name still throws
When it happens
Trigger: Slot-name typos ('product.form-sidebar' vs 'product.form_sidebar'); id typos or case mismatch; calling updateSlot before the entry was registered; updating an entry a newer dashboard version renamed or removed; updating after removeSlot.
Common situations: Plugins patching built-in slot entries by guessed names/ids; dashboard upgrades reorganizing built-in slots; string constants for slot names drifting between packages.
Related errors
- Search entry "${key}" not found.
- Settings nav entry "${key}" not found.
- Slot "${name}" already has an entry with id "${entry.id}". U
- Plugin route "${entry.key}" already registered.
- Search entry "${entry.key}" already registered. Use searchRe
AI-assisted analysis of spree/spree@06bf66a868 (2026-08-21).
Data as JSON: /api/errors/83c765cd8958c2b7.
Report an issue: GitHub.