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

  1. Define the example as a plain public instance method on the preview subclass: def my_example; render(MyComponent.new); end.
  2. Fix the URL/spec to match an existing example name (names are the sorted method names; check via UserPreview.examples in the console).
  3. If examples live in a shared parent class, redefine or delegate them in each concrete preview class, since inherited methods are not listed.
  4. 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

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


AI-assisted analysis of ViewComponent/view_component@9f22c36fa7 (2026-08-23). Data as JSON: /api/errors/b3b3a6c3f6c141da. Report an issue: GitHub.