heroui-inc/heroui · warning

Duplicate collection slot "${name}". Use a unique, namespace

Error message

Duplicate collection slot "${name}". Use a unique, namespaced name (e.g. "tabs.listContainer", "menu.popover").

What it means

HeroUI registers collection slot names (used to inject collection props into arbitrary components) in a dev-only registry. If two different call sites create a collection slot with the same name, the library warns about duplicates to catch collisions where one slot could overwrite another's injected props. The name is still registered/used; it is a diagnostic warning in development only.

Source

Thrown at packages/react/src/utils/collection-prop-injection.tsx:30

let registry: Set<string> | undefined;

const __DEV__ = typeof process !== "undefined" && process.env?.["NODE_ENV"] !== "production";

/**
 * Create a CollectionBuilder-safe slot for optional chrome around a RAC collection
 * target (e.g. TabList, ListBox).
 *
 * The injector emits no host DOM: chrome props are provided via Context and a
 * string-keyed `cloneElement` channel (React strips Symbol keys from element props).
 * The target should apply chrome through the RAC `render` prop — not by wrapping
 * the collection child in a host node.
 */
export const createCollectionSlot = <T extends object>(name: string) => {
  if (__DEV__) {
    registry ??= new Set<string>();

    if (registry.has(name)) {
      logger.warn(
        `Duplicate collection slot "${name}". Use a unique, namespaced name (e.g. "tabs.listContainer", "menu.popover").`,
      );
    }

    registry.add(name);
  }

  // String key required — React drops Symbol keys from element props / cloneElement.
  const key = `$$heroui.collection.${name}`;
  const SlotContext = createContext<T | undefined>(undefined);

  const inject = (children: ReactNode, value: T): ReactNode => {
    return Children.map(children, (child) => {
      if (!isValidElement(child)) {
        return child;
      }

      return React.cloneElement(child as ReactElement<Record<string, unknown>>, {

View on GitHub (pinned to 7546fff813)

Solutions

  1. Rename the slot to a unique namespaced name like "<component>.<slot>" (e.g. "tabs.listContainer", "menu.popover")
  2. Search the repo for the existing createCollectionSlot call with that name and pick a different one
  3. Follow the established naming convention when adding new collection slots

Example fix

// before
export const ListContainerSlot = createCollectionSlot("listContainer");

// after
export const ListContainerSlot = createCollectionSlot("tabs.listContainer");
Defensive patterns

Strategy: validation

Validate before calling

// Before registering, check uniqueness across your codebase:
// grep -r "createCollectionSlot(" packages/
// Use namespaced names: `${componentName}.${slotName}`

Prevention

When it happens

Trigger: Calling createCollectionSlot("listContainer") from two different components, or using an unnamespaced generic name like "container" in more than one place; only fires when __DEV__ is true.

Common situations: Contributing a new component that uses createCollectionSlot with a name already taken by another component; using generic slot names like "base" or "item" instead of namespaced ones.


AI-assisted analysis of heroui-inc/heroui@7546fff813 (2026-08-28). Data as JSON: /api/errors/7eb37cebf56b4f8a. Report an issue: GitHub.