heartcombo/simple_form · error · WrapperNotFound

Couldn't find wrapper with name #{name}

Error message

Couldn't find wrapper with name #{name}

What it means

SimpleForm.wrapper(name) looks up a named wrapper registered via SimpleForm.wrappers(:name) { |b| ... } in a registry hash keyed by the stringified name (lib/simple_form.rb:209,221-223). When the key is absent it raises SimpleForm::WrapperNotFound. The lookup happens at render time whenever a form or input references a wrapper by name (the wrapper: and wrapper_mappings: options), so the error surfaces while rendering a view whose wrapper was never defined.

Source

Thrown at lib/simple_form.rb:222

  ## WRAPPER CONFIGURATION
  # The default wrapper to be used by the FormBuilder.
  mattr_accessor :default_wrapper
  @@default_wrapper = :default
  @@wrappers = {} #:nodoc:

  mattr_accessor :i18n_scope
  @@i18n_scope = 'simple_form'

  mattr_accessor :input_field_error_class
  @@input_field_error_class = nil

  mattr_accessor :input_field_valid_class
  @@input_field_valid_class = nil

  # Retrieves a given wrapper
  def self.wrapper(name)
    @@wrappers[name.to_s] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
  end

  # Raised when fails to find a given wrapper name
  class WrapperNotFound < StandardError
  end

  # Define a new wrapper using SimpleForm::Wrappers::Builder
  # and store it in the given name.
  def self.wrappers(*args, &block)
    if block_given?
      options                 = args.extract_options!
      name                    = args.first || :default
      @@wrappers[name.to_s]   = build(options, &block)
    else
      @@wrappers
    end
  end

View on GitHub (pinned to 18f38aad0b)

Solutions

  1. Define the missing wrapper in config/initializers/simple_form.rb: SimpleForm.setup { |config| config.wrappers :horizontal do |b| ... end }
  2. Fix the name in the wrapper: / wrapper_mappings: option so it matches an existing key (names are matched as strings, symbol vs string does not matter, only spelling does)
  3. If the custom wrapper is not needed, remove the wrapper: option so the form falls back to SimpleForm.default_wrapper (default :default)
  4. Verify what is registered at boot with Rails.logger.info SimpleForm.wrappers.keys.inspect and compare against the names your views use

Example fix

# before (app/views/users/_form.html.erb)
<%= simple_form_for @user, wrapper: :horizontal_form do |f| %>
  <%= f.input :name %>  <!-- WrapperNotFound: Couldn't find wrapper with name horizontal_form -->
<% end %>

# after (config/initializers/simple_form.rb)
SimpleForm.setup do |config|
  config.wrappers :horizontal_form, tag: :div, class: :form-row do |b|
    b.use :html5
    b.use :label_input
    b.use :error, wrap_with: { tag: :span, class: :error }
  end
  config.default_wrapper = :horizontal_form
end
Defensive patterns

Strategy: validation

Validate before calling

# before rendering a form that uses a named wrapper
wrapper_name = :horizontal
unless SimpleForm.wrappers.key?(wrapper_name.to_s)
  raise ArgumentError, "wrapper :#{wrapper_name} is not defined. Defined: #{SimpleForm.wrappers.keys.sort.join(', ')}"
end
simple_form_for @user, wrapper: wrapper_name do |f|
  # ...
end

Type guard

def wrapper_defined?(name)
  SimpleForm.wrappers.key?(name.to_s)
end

wrapper_defined?(:horizontal) # => true/false; registry keys are strings

Try / catch

begin
  SimpleForm.wrapper(wrapper_name)   # pre-resolve before render
rescue SimpleForm::WrapperNotFound => e
  Rails.logger.warn("#{e.message}; falling back to #{SimpleForm.default_wrapper}")
  wrapper_name = SimpleForm.default_wrapper
end

Prevention

When it happens

Trigger: Calling simple_form_for @user, wrapper: :horizontal when 'horizontal' is not a key in SimpleForm.wrappers; passing f.input :name, wrapper: :compact or wrapper_mappings: { boolean: :vertical_boolean } for a wrapper name never registered in config/initializers/simple_form.rb; referencing a wrapper defined in an initializer that failed to load.

Common situations: Upgrading simple_form and replacing the old initializer (which held custom wrapper definitions) with a freshly generated one; copying views from another app that uses wrappers your config never defined; a per-form wrapper: option left behind after the wrapper was renamed or removed from the initializer; typos in the wrapper name.

Related errors


AI-assisted analysis of heartcombo/simple_form@18f38aad0b (2026-08-21). Data as JSON: /api/errors/c35c3ae91636d904. Report an issue: GitHub.