Skip to content

Fix Vector<float[]> serialization + non-generic enumeration with FloatVectorizer (#566)#569

Merged
slorello89 merged 1 commit into
mainfrom
fix-float-vectorizer-serialization
Jun 2, 2026
Merged

Fix Vector<float[]> serialization + non-generic enumeration with FloatVectorizer (#566)#569
slorello89 merged 1 commit into
mainfrom
fix-float-vectorizer-serialization

Conversation

@slorello89

@slorello89 slorello89 commented Jun 2, 2026

Copy link
Copy Markdown
Member

Fixes #566.

A model using Vector<float[]> with [FloatVectorizer] returned to a GraphQL layer (Hot Chocolate) came back as an empty collection even though the document was present in Redis. Investigation turned up two independent bugs, both fixed here.

1. Vector<float[]> serialized as an object instead of a flat array

In VectorJsonConverter.Write, the flat-array fast path for a FloatVectorizer was guarded by:

if (_vectorizerAttribute is FloatVectorizerAttribute && value is Vector<double[]> floatVector)

For a Vector<float[]>, value is Vector<double[]> is always false, so the embedding fell through to the generic path and was written as a structured object:

"Vec": { "Value": "[0.1,0.2]", "Vector": [0.1,0.2] }

But for a FloatVectorizer the index points the bare path ($.Vec AS Vec VECTOR …) at the field. RediSearch can't extract a vector from an object, so the document failed to index (hash_indexing_failures increments, num_docs stays 0) — JSON.SET still succeeds, which is why the data is visible in the console but absent from every search. The Read path already assumes Vector<float[]>, confirming the Write guard was a copy/paste bug.

Fix: correct the guard to value is Vector<float[]>.

2. Non-generic IEnumerable.GetEnumerator() always threw

RedisCollection's explicit IEnumerable.GetEnumerator() routed through Provider.Execute<IEnumerable>(Expression), which only implements scalar terminal operators (First/Sum/Count/…) and threw NotImplementedException for every enumeration shape. Hot Chocolate enumerates resolver results through the non-generic IEnumerable interface, so handing it the collection as an IQueryable always failed — independent of the vector field.

Fix: defer to the generic GetEnumerator() (the canonical foreach/.ToList() path).

Validation

Reproduced the reporter's exact setup locally (ASP.NET Core + Hot Chocolate, the issue's Floater model, referencing the local build). Before: stored {"Value":...,"Vector":[...]}, num_docs 0, hash_indexing_failures 1, GraphQL {"floaters":[]}. After: stored [0.1,0.2], num_docs 1, 0 failures, GraphQL returns the document.

Tests

  • FloatVectorIsIndexedAndEnumerable — inserts a Vector<float[]> + [FloatVectorizer] doc (a combo with zero prior coverage), asserts hash_indexing_failures == 0, and asserts a plain enumeration returns it.
  • EnumeratesThroughNonGenericIEnumerable — enumerates a collection (bare and Where-filtered) through the non-generic IEnumerable interface.

Both verified to fail on the old code and pass with the fixes.

🤖 Generated with Claude Code

The Write path in VectorJsonConverter guarded the flat-array branch for a
FloatVectorizer with `value is Vector<double[]>`, which is never true for a
Vector<float[]>. As a result the embedding was written as an object
({"Value":...,"Vector":[...]}) instead of a flat array, while the index
(correctly) points the bare path at a VECTOR field. RediSearch could not
extract a vector from the object, so the document failed to index
(hash_indexing_failures) and every search - including the unfiltered
enumeration IRedisCollection<T> issues - returned empty even though the
document was present in Redis.

Correct the type guard to Vector<float[]> and add a functional regression
test covering insert + plain enumeration + zero indexing failures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jit-ci

jit-ci Bot commented Jun 2, 2026

Copy link
Copy Markdown

🛡️ Jit Security Scan Results

CRITICAL HIGH MEDIUM

✅ No security findings were detected in this PR


Security scan by Jit

@slorello89 slorello89 merged commit 75e99dc into main Jun 2, 2026
3 checks passed
@slorello89 slorello89 changed the title Fix Vector<float[]> serialization with FloatVectorizer (#566) Fix Vector<float[]> serialization + non-generic enumeration with FloatVectorizer (#566) Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IRedisCollection<T> fails with Vector fields

1 participant