redis/redis-rb · error · Redis::CommandError

Vector fields cannot have no_index option

Error message

Vector fields cannot have no_index option

What it means

NOINDEX on a VECTOR field is rejected client-side: vector fields exist solely to be searched (KNN and vector range queries), so an unindexed vector column is meaningless. Unlike TAG or TEXT there is no store-but-do-not-index use case, so VectorField raises Redis::CommandError for no_index: true before FT.CREATE is sent (lib/redis/commands/modules/search/field.rb:256).

Source

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

        # @param [String, Symbol] name the document attribute the field indexes
        # @param [String, Symbol] algorithm the indexing method, one of +FLAT+, +HNSW+, +SVS-VAMANA+
        # @param [Hash] attributes the vector attributes (e.g. +type+, +dim+, +distance_metric+)
        # @option options [String] :as an alias for the field, rendered as +AS <alias>+
        # @raise [ArgumentError] if +algorithm+ is not a supported indexing method
        # @raise [Redis::CommandError] if +:sortable+ or +:no_index+ is given
        def initialize(name, algorithm, attributes = {}, **options)
          # Validate algorithm
          unless ['FLAT', 'HNSW', 'SVS-VAMANA'].include?(algorithm.to_s.upcase)
            raise ArgumentError,
                  "Realtime vector indexing supporting 3 Indexing Methods: 'FLAT', 'HNSW', and 'SVS-VAMANA'"
          end

          # Validate that sortable and no_index are not used with vector fields
          if options[:sortable]
            raise Redis::CommandError, "Vector fields cannot be sortable"
          end
          if options[:no_index]
            raise Redis::CommandError, "Vector fields cannot have no_index option"
          end

          super(name, :vector, **options)
          @algorithm = algorithm.to_s.upcase
          @attributes = attributes.transform_keys { |k| k.to_s.upcase }.transform_values { |v| v.to_s.upcase }
        end

        # Set or override a single vector attribute.
        #
        # @param [String, Symbol] key the attribute name (upcased internally)
        # @param [Object] value the attribute value
        # @return [Object] the stored value
        def add_attribute(key, value)
          # Normalize like #initialize does for the kwargs form, so block-DSL attributes
          # (vector_field(...) { type "float32" }) reach FT.CREATE with the expected casing.
          @attributes[key.to_s.upcase] = value.to_s.upcase
        end

View on GitHub (pinned to 2ba9010b91)

Solutions

  1. Remove no_index from the vector field
  2. Store unindexed raw vectors as ordinary document attributes outside the schema instead of as a VECTOR field
  3. Keep separate option sets for metadata fields and vector fields

Example fix

// before
VectorField.new("emb", "HNSW", attrs, no_index: true)
// after
VectorField.new("emb", "HNSW", attrs) # raw copy lives in a non-schema attribute
Defensive patterns

Strategy: validation

Validate before calling

def vector_field(name, algo, attrs, opts)
  VectorField.new(name, algo, attrs, **opts.except(:no_index, :sortable))
end

Type guard

field.is_a?(Redis::Commands::Search::Field::VectorField) ? opts.except(:no_index) : opts

Try / catch

begin
  VectorField.new(name, algo, attrs, **opts)
rescue Redis::CommandError => e
  raise SchemaConfigError, "vector field rejected: #{e.message}"
end

Prevention

When it happens

Trigger: VectorField.new("emb", "HNSW", attrs, no_index: true); reusing a metadata options hash (which used no_index to skip indexing) for a new embedding field.

Common situations: Schemas that mark helper fields NOINDEX by convention; adding embeddings to an existing document model and copying field boilerplate; storing raw vectors next to indexed ones under one shared definition.

Related errors


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