{"record":{"id":"7488a7901ae49a81","repo":"ViewComponent/view_component","slug":"component-declares-the-slot-name-slot-multiple-tim","errorCode":null,"errorMessage":"COMPONENT declares the SLOT_NAME slot multiple times.\n\nTo fix this issue, choose a different slot name.","messagePattern":"COMPONENT declares the SLOT_NAME slot multiple times\\.\n\nTo fix this issue, choose a different slot name\\.","errorType":"exception","errorClass":"ViewComponent::RedefinedSlotError","httpStatus":null,"severity":"error","filePath":"lib/view_component/slotable.rb","lineNumber":333,"sourceCode":"      end\n\n      def __vc_validate_singular_slot_name(slot_name)\n        if slot_name.to_sym == :content\n          raise ContentSlotNameError.new(name)\n        end\n\n        if RESERVED_NAMES[:singular].include?(slot_name.to_sym)\n          raise ReservedSingularSlotNameError.new(name, slot_name)\n        end\n\n        __vc_raise_if_slot_conflicts_with_call(slot_name)\n        __vc_raise_if_slot_ends_with_question_mark(slot_name)\n        __vc_raise_if_slot_registered(slot_name)\n      end\n\n      def __vc_raise_if_slot_registered(slot_name)\n        if registered_slots.key?(slot_name)\n          raise RedefinedSlotError.new(name, slot_name)\n        end\n      end\n\n      def __vc_raise_if_slot_ends_with_question_mark(slot_name)\n        raise SlotPredicateNameError.new(name, slot_name) if slot_name.to_s.end_with?(\"?\")\n      end\n\n      def __vc_raise_if_slot_conflicts_with_call(slot_name)\n        if slot_name.start_with?(\"call_\")\n          raise InvalidSlotNameError, \"Slot cannot start with 'call_'. Please rename #{slot_name}\"\n        end\n      end\n\n      def __vc_raise_if_slot_name_uncountable(slot_name)\n        slot_name = slot_name.to_s\n        if slot_name.pluralize == slot_name.singularize\n          raise UncountableSlotNameError.new(name, slot_name)\n        end","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/ViewComponent/view_component/blob/9f22c36fa7d7b44098a8ed97472e3b4674ae420f/lib/view_component/slotable.rb#L315-L351","documentation":"Raised by __vc_raise_if_slot_registered when the name is already present in registered_slots (lib/view_component/slotable.rb:331-335). Slots are declared once: the first registration generates the getter, predicate and setter methods, and a second registration is refused rather than redefined. Subclasses clone registered_slots through inherited (lib/view_component/slotable.rb:198-201), so redeclaring a parent slot in a child also raises.","triggerScenarios":"The same declaration twice in one class, for example renders_one :header followed by renders_one :header; mixing kinds on one name family, because renders_one validates the pluralized name at :81 and renders_many validates the singularized name at :151, so renders_one :item next to renders_many :items raises either way; and redeclaring any slot inherited from a parent component.","commonSituations":"Copy-pasted slot blocks; refactoring between renders_one and renders_many while keeping the same name; subclasses that try to override or re-register an inherited slot; code generators that append declarations without checking existing ones.","solutions":["Delete the duplicate declaration; the first one already works","In a subclass, remove the redeclaration: inherited slots are cloned and keep working without new code","If the subclass needs a genuinely different slot, choose a new name instead of the parent slot name","When switching a slot between renders_one and renders_many, replace the old declaration in the same edit rather than keeping both"],"exampleFix":"# before\nclass ListComponent < ViewComponent::Base\n  renders_one :item, ItemComponent\n  renders_many :items, ItemComponent # raises RedefinedSlotError on :item\nend\n\n# after\nclass ListComponent < ViewComponent::Base\n  renders_many :items, ItemComponent # one concept, one name family\nend","handlingStrategy":"validation","validationCode":"def slot_name_family_free?(klass, name)\n  candidates = [name.to_sym, name.to_s.singularize.to_sym, name.to_s.pluralize.to_sym].uniq\n  (candidates & klass.registered_slots.keys).empty?\nend\n\nslot_name_family_free?(ListComponent, :items) # => false once :items or :item is registered","typeGuard":null,"tryCatchPattern":"# treat config-driven registration as idempotent\nbegin\n  register_slot_from_config(name)\nrescue ViewComponent::RedefinedSlotError\n  # the slot already exists; skip instead of failing the whole component load\nend","preventionTips":["Declare each concept once: choose the singular or the plural form, never both","Never redeclare inherited slots in subclasses; rely on the cloned registration","Search the component and its ancestors for a name before adding a new slot","Assert the expected set of registered_slots keys in a spec when slots come from configuration"],"tags":["ruby","rails","view-component","slots","duplicate-definition","inheritance"],"backgroundTag":"duplicate-definition","analyzedSha":"9f22c36fa7d7b44098a8ed97472e3b4674ae420f","analyzedAt":"2026-08-23T10:20:47.008Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}