redis/redis-rb · error · ArgumentError

Invalid phonetic matcher. Supported matchers are: #{valid_ma

Error message

Invalid phonetic matcher. Supported matchers are: #{valid_matchers.join(', ')}

What it means

The phonetic option on a TEXT field enables Double Metaphone matching, so searches also match similar-sounding words. Redis supports exactly four matchers: dm:en, dm:fr, dm:pt, dm:es. TextField validates the value at construction time (lib/redis/commands/modules/search/field.rb:100); the comparison is exact and case-sensitive, so DM:EN is rejected along with unknown codes.

Source

Thrown at lib/redis/commands/modules/search/field.rb:100

        end
      end

      # A +TEXT+ field, indexing full-text searchable content.
      class TextField < Field
        # Build a +TEXT+ field.
        #
        # @param [String, Symbol] name the document attribute the field indexes
        # @param [Query, nil] query a query the field is bound to, enabling {#match}
        # @option options [Numeric] :weight the field's scoring weight (+WEIGHT+)
        # @option options [String] :phonetic phonetic matcher, one of +dm:en+, +dm:fr+, +dm:pt+, +dm:es+ (+PHONETIC+)
        # @option options [Boolean] :no_stem disable stemming (+NOSTEM+)
        # @raise [ArgumentError] if +:phonetic+ is not a supported matcher
        def initialize(name, query = nil, **options)
          super(name, :text, query, **options)
          if options[:phonetic]
            valid_matchers = ['dm:en', 'dm:fr', 'dm:pt', 'dm:es']
            unless valid_matchers.include?(options[:phonetic])
              raise ArgumentError, "Invalid phonetic matcher. Supported matchers are: #{valid_matchers.join(', ')}"
            end
          end
        end

        # Render this field as the array of +FT.CREATE+ +SCHEMA+ tokens.
        #
        # @return [Array] the schema tokens for this field
        def to_args
          args = [@name]
          args << "AS" << @alias_name if @alias_name
          args << @type.to_s.upcase
          args << "NOSTEM" if @options[:no_stem]
          args << "WEIGHT" << @options[:weight].to_s if @options[:weight]
          args << "PHONETIC" << @options[:phonetic] if @options[:phonetic]

          # Add suffix options in specific order: no_index, index_missing, index_empty, sortable, withsuffixtrie
          args << "NOINDEX" if @options[:no_index]
          args << "INDEXMISSING" if @options[:index_missing]

View on GitHub (pinned to 2ba9010b91)

Solutions

  1. Use one of the exact lowercase strings dm:en, dm:fr, dm:pt, dm:es
  2. Drop the phonetic option entirely if the language you need is not in the list
  3. Keep matcher strings out of case-normalizing config layers

Example fix

// before
TextField.new("name", phonetic: "dm:de")
// after
TextField.new("name", phonetic: "dm:fr")
Defensive patterns

Strategy: validation

Validate before calling

PHONETIC_MATCHERS = %w[dm:en dm:fr dm:pt dm:es].freeze

ph = schema_config.fetch("phonetic", nil)
raise ArgumentError, "unsupported phonetic matcher: #{ph}" if ph && !PHONETIC_MATCHERS.include?(ph)

Type guard

ph.nil? || %w[dm:en dm:fr dm:pt dm:es].include?(ph)

Try / catch

begin
  TextField.new(name, phonetic: ph)
rescue ArgumentError => e
  raise SchemaConfigError, e.message
end

Prevention

When it happens

Trigger: TextField.new("name", phonetic: "dm:de") (German is not shipped); phonetic: "en" without the dm: prefix; phonetic: "DM:EN" after an upcasing config layer.

Common situations: Assuming every Double Metaphone language code exists (dm:de is the usual guess); schema option values passed through case-normalizing config code; typos in schema definitions copied from docs.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of redis/redis-rb@2ba9010b91 (2026-08-23). Data as JSON: /api/errors/f0c09ab3f417420c. Report an issue: GitHub.