ViewComponent/view_component · error · AbstractController::ActionNotFound
#{example} is not a valid preview example
Error message
#{example} is not a valid preview example What it means
Preview examples are public instance methods defined directly on a class inheriting ViewComponent::Preview; Preview.examples collects them via public_instance_methods(false), which excludes inherited and private methods. Preview.render_args raises AbstractController::ActionNotFound ('<example> is not a valid preview example') when the requested example name is not in that list. This is the error behind the preview routes (/rails/view_components/<preview>/<example>) when the example segment does not map to a method.
Source
Thrown at lib/view_component/preview.rb:43
def render_with_template(template: nil, locals: {})
{
template: template,
locals: locals
}
end
class << self
# Returns all component preview classes.
def all
__vc_load_previews
descendants
end
# Returns the arguments for rendering of the component in its layout
def render_args(example, params: {})
raise AbstractController::ActionNotFound, "#{example} is not a valid preview example" unless examples.include?(example.to_s)
example_params_names = instance_method(example).parameters.map(&:last)
provided_params = params.slice(*example_params_names).to_h.symbolize_keys
result = provided_params.empty? ? new.public_send(example) : new.public_send(example, **provided_params)
result ||= {}
result[:template] = preview_example_template_path(example) if result[:template].nil?
@layout = nil unless defined?(@layout)
result.merge(layout: @layout)
end
# Returns all of the available examples for the component preview.
def examples
public_instance_methods(false).map(&:to_s).sort
end
# Returns +true+ if the preview exists.
def exists?(preview)
all.any? { |p| p.preview_name == preview }View on GitHub (pinned to 9f22c36fa7)
Solutions
- Define the example as a plain public instance method on the preview subclass: def my_example; render(MyComponent.new); end.
- Fix the URL/spec to match an existing example name (names are the sorted method names; check via UserPreview.examples in the console).
- If examples live in a shared parent class, redefine or delegate them in each concrete preview class, since inherited methods are not listed.
- Remove private/protected from the example method so it shows up in .examples.
Example fix
# before
class UserPreview < ViewComponent::Preview
private # makes the example invisible to .examples
def default
render(UserComponent.new(user: users(:one)))
end
end
# after
class UserPreview < ViewComponent::Preview
def default
render(UserComponent.new(user: users(:one)))
end
end Defensive patterns
Strategy: validation
Validate before calling
example = "default"
raise ArgumentError, "#{example} not in #{UserPreview.examples}" unless UserPreview.examples.include?(example)
UserPreview.render_args(example) Try / catch
begin UserPreview.render_args(example, params: params) rescue AbstractController::ActionNotFound head :not_found # or redirect to the preview index end
Prevention
- Keep preview examples public instance methods on the concrete preview class.
- In preview controllers or specs, check Preview.examples.include?(name) before calling render_args.
- When renaming examples, update links/specs and grep for the old URL segment.
When it happens
Trigger: Visiting /rails/view_components/user_preview/nonexistent with a typo'd or removed example name; defining the example as private or protected in the preview class; defining examples on a shared parent preview class (inherited methods are excluded by public_instance_methods(false)); calling render_args('default') from code after the method was renamed.
Common situations: Renaming or deleting a preview method while bookmarks or feature specs still point at the old URL; extracting shared examples into a base preview class during a refactor and having them disappear from examples; accidentally making example methods private.
Related errors
- A preview template for example EXAMPLE doesn't exist. To fi
- Inline templates can only be defined once per-component.
- wrong number of arguments (given #{args.size}, expected 1)
- Cannot serialize render_later with a block
- Cannot deserialize unknown component: #{hash["component_clas
AI-assisted analysis of ViewComponent/view_component@9f22c36fa7 (2026-08-23).
Data as JSON: /api/errors/b3b3a6c3f6c141da.
Report an issue: GitHub.