thoughtbot/shoulda-matchers · error · ArgumentError

'#{name}' is not registered

Error message

'#{name}' is not registered

What it means

This ArgumentError is raised by Shoulda::Matchers::Integrations::Registry#find_class! (lib/shoulda/matchers/integrations/registry.rb:20-24), the internal symbol-to-class map that backs the `with.test_framework` and `with.library` calls inside a Shoulda::Matchers.configure block. When you pass a name to either method, Integrations::Configuration calls find_test_framework!/find_library!, which does registry.fetch(name) and raises ArgumentError when that symbol was never registered at require time. In practice it means the symbol you typed is not one of the gem's known integration names: it is typo'd, invented, a String instead of a Symbol, or a name passed to the wrong method (a library name given to with.test_framework, or vice versa).

Source

Thrown at lib/shoulda/matchers/integrations/registry.rb:22

      # @private
      class Registry
        def register(klass, name)
          registry[name] = klass
        end

        def find!(name)
          find_class!(name).new
        end

        private

        def registry
          @_registry ||= {}
        end

        def find_class!(name)
          registry.fetch(name) do
            raise ArgumentError, "'#{name}' is not registered"
          end
        end
      end
    end
  end
end

View on GitHub (pinned to 79cdfbc326)

Solutions

  1. Fix the symbol to a registered name: test frameworks are :rspec, :minitest (aliased to :minitest_5), :minitest_4, :test_unit, :active_support_test_case; libraries are :rails, :active_record, :active_model, :action_controller, :routing.
  2. Give each method the right kind of name: `with.test_framework :minitest_5` plus `with.library :rails` — never `with.test_framework :rails`, because :rails lives in the library registry.
  3. Pass Symbols, not Strings: registry keys are Symbols, so with.test_framework 'rspec' raises while with.test_framework :rspec works.
  4. If the snippet came from documentation for another version, check the shoulda-matchers version in your Gemfile.lock against that doc's version and re-copy the configure block from the matching README.

Example fix

# before
Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rails        # ArgumentError: "':rails' is not registered"
    with.library :minitest
  end
end

# after
Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :minitest_5   # frameworks: :rspec, :minitest, :minitest_4, :test_unit, :active_support_test_case
    with.library :rails               # libraries: :rails, :active_record, :active_model, :action_controller, :routing
  end
end
Defensive patterns

Strategy: validation

Validate before calling

SHOULD_FRAMEWORKS = %i[
  rspec minitest minitest_5 minitest_4 test_unit active_support_test_case
].freeze
SHOULD_LIBRARIES = %i[
  rails active_record active_model action_controller routing
].freeze

def configure_shoulda!(framework:, library: :rails)
  unless SHOULD_FRAMEWORKS.include?(framework)
    raise ArgumentError, "#{framework.inspect} is not a registered test framework (#{SHOULD_FRAMEWORKS.join(', ')})"
  end
  unless SHOULD_LIBRARIES.include?(library)
    raise ArgumentError, "#{library.inspect} is not a registered library (#{SHOULD_LIBRARIES.join(', ')})"
  end

  Shoulda::Matchers.configure do |config|
    config.integrate do |with|
      with.test_framework framework
      with.library library
    end
  end
end

Type guard

def valid_test_framework?(name)
  %i[rspec minitest minitest_5 minitest_4 test_unit active_support_test_case].include?(name)
end

def valid_library?(name)
  %i[rails active_record active_model action_controller routing].include?(name)
end

Try / catch

begin
  Shoulda::Matchers.configure do |config|
    config.integrate do |with|
      with.test_framework framework_name
      with.library library_name
    end
  end
rescue ArgumentError => e
  raise ArgumentError, "Bad shoulda-matchers integration name (framework=#{framework_name.inspect}, library=#{library_name.inspect}): #{e.message}"
end

Prevention

When it happens

Trigger: Calling `with.test_framework` with an unregistered symbol: :rspec2, :Minitest (capitalized), :active_support (the registered name is :active_support_test_case), or the string 'rspec' instead of the symbol :rspec (the registry hash is keyed by Symbols). Calling `with.test_framework :rails` — :rails is registered in the library registry (:rails, :active_record, :active_model, :action_controller, :routing), not the framework registry (:rspec, :minitest, :minitest_5, :minitest_4, :test_unit, :active_support_test_case), so the framework lookup fails. Calling `with.library :minitest` or `with.library :factory_bot` — :minitest is a framework and :factory_bot is not an integration name at all. The raise happens synchronously while the configure block runs, i.e. at test-suite boot.

Common situations: Typos when hand-copying the configure block from the README; swapping the framework and library arguments; copying a snippet written for a different shoulda-matchers major version (the with.* DSL and mandatory configuration arrived in 3.0, so pre-3.0 or post-3.0 examples use different names); passing a String like "minitest_5" instead of a Symbol; expecting a favorite gem (factory_bot, capybara) to be a registrable library when only the Rails component libraries exist.

Related errors


AI-assisted analysis of thoughtbot/shoulda-matchers@79cdfbc326 (2026-08-23). Data as JSON: /api/errors/dd2c981fd1ff4611. Report an issue: GitHub.