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
- Use one of the exact lowercase strings dm:en, dm:fr, dm:pt, dm:es
- Drop the phonetic option entirely if the language you need is not in the list
- 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
- Whitelist phonetic values against the four dm: codes
- Do not upcase or normalize matcher strings
- Cover the matcher value in schema config tests
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
- Realtime vector indexing supporting 3 Indexing Methods: 'FLA
- Invalid schema
- collect fields must be :all or a non-empty list
- nx and xx are mutually exclusive
- fpha accepts only: #{JSON_SET_FPHA_TYPES.join(', ')}
AI-assisted analysis of redis/redis-rb@2ba9010b91 (2026-08-23).
Data as JSON: /api/errors/f0c09ab3f417420c.
Report an issue: GitHub.