ViewComponent/view_component · error · ViewComponent::SlotPredicateNameError
COMPONENT declares a slot named SLOT_NAME, which ends with a
Error message
COMPONENT declares a slot named SLOT_NAME, which ends with a question mark. This isn't allowed because the ViewComponent framework already provides predicate methods ending in `?`. To fix this issue, choose a different name.
What it means
Raised when a slot name ends with a question mark (lib/view_component/slotable.rb:337-339). For every registered slot the framework defines a predicate method named <slot>? (for example items? at lib/view_component/slotable.rb:179), so a slot literally carrying a question mark would fight the generated predicate and Ruby method naming. The check runs in both the singular and the plural validators.
Source
Thrown at lib/view_component/slotable.rb:338
end
if RESERVED_NAMES[:singular].include?(slot_name.to_sym)
raise ReservedSingularSlotNameError.new(name, slot_name)
end
__vc_raise_if_slot_conflicts_with_call(slot_name)
__vc_raise_if_slot_ends_with_question_mark(slot_name)
__vc_raise_if_slot_registered(slot_name)
end
def __vc_raise_if_slot_registered(slot_name)
if registered_slots.key?(slot_name)
raise RedefinedSlotError.new(name, slot_name)
end
end
def __vc_raise_if_slot_ends_with_question_mark(slot_name)
raise SlotPredicateNameError.new(name, slot_name) if slot_name.to_s.end_with?("?")
end
def __vc_raise_if_slot_conflicts_with_call(slot_name)
if slot_name.start_with?("call_")
raise InvalidSlotNameError, "Slot cannot start with 'call_'. Please rename #{slot_name}"
end
end
def __vc_raise_if_slot_name_uncountable(slot_name)
slot_name = slot_name.to_s
if slot_name.pluralize == slot_name.singularize
raise UncountableSlotNameError.new(name, slot_name)
end
end
end
def __vc_get_slot(slot_name)
@__vc_set_slots ||= {}View on GitHub (pinned to 9f22c36fa7)
Solutions
- Remove the question mark from the slot name
- Rely on the generated presence predicate: after renders_one :available the template calls available?
- Sanitize generated names by stripping a trailing question mark before passing them to renders_one or renders_many
Example fix
# before class BadgeComponent < ViewComponent::Base renders_one :verified? # raises SlotPredicateNameError end # after class BadgeComponent < ViewComponent::Base renders_one :verified # template: show the badge when verified? end
Defensive patterns
Strategy: validation
Validate before calling
def slot_name_safe?(name)
!name.to_s.end_with?("?")
end
slot_name_safe?(:available?) # => false Try / catch
begin
renders_one(candidate.to_sym)
rescue ViewComponent::InvalidSlotNameError
# covers SlotPredicateNameError plus the reserved, call_-prefixed and uncountable subclasses
candidate = candidate.to_s.chomp("?")
retry
end Prevention
- Never put a question mark in a slot name; every slot already gets a free predicate method
- Strip trailing question marks from generated or CMS-driven names before declaration
When it happens
Trigger: renders_one :available?, renders_many :active?, or any string or symbol passed to either macro whose to_s form ends with a question mark, including names generated from CMS field keys or I18n keys that contain one.
Common situations: Copying the Ruby predicate idiom into slot names for boolean-ish optional areas; generated slot names from data that include question marks; renaming a helper method such as confirmed? into a slot during a component refactor.
Related errors
- COMPONENT declares a slot named SLOT_NAME, which is a reserv
- Slot cannot start with 'call_'. Please rename #{slot_name}
- COMPONENT declares a slot named SLOT_NAME, which is an uncou
- A method called 'SETTER_METHOD_NAME' already exists and woul
- COMPONENT declares a slot named content, which is a reserved
AI-assisted analysis of ViewComponent/view_component@9f22c36fa7 (2026-08-23).
Data as JSON: /api/errors/049b3fc392b9e8ca.
Report an issue: GitHub.