Skip to content

Python: fix(python/redis): wrap IndexDefinition prefix in a list#13898

Open
Doondi-Ashlesh wants to merge 2 commits intomicrosoft:mainfrom
Doondi-Ashlesh:fix/redis-index-definition-prefix-list
Open

Python: fix(python/redis): wrap IndexDefinition prefix in a list#13898
Doondi-Ashlesh wants to merge 2 commits intomicrosoft:mainfrom
Doondi-Ashlesh:fix/redis-index-definition-prefix-list

Conversation

@Doondi-Ashlesh
Copy link
Copy Markdown

Summary

Fixes #13894

redis-py's IndexDefinition expects prefix to be a list or tuple. In python/semantic_kernel/connectors/redis.py:281 the prefix was passed as a bare string:

# Before
index_definition = IndexDefinition(
    prefix=f"{self.collection_name}:", ...
)

Because Python iterates a string character-by-character, redis-py was building a FT.CREATE PREFIX command with each character as a separate prefix entry instead of the intended single prefix. This caused create_collection to fail with a malformed command.

Change

# After
index_definition = IndexDefinition(
    prefix=[f"{self.collection_name}:"], ...
)

Wrapping the string in a list ensures a single, correctly formed prefix is passed to FT.CREATE.

Testing

  • Existing unit tests in python/tests/unit/connectors/memory/test_redis_store.py continue to pass.
  • Manually verified that FT.CREATE now receives the correct PREFIX 1 <collection_name>: argument.

Signed-off-by: Doondi-Ashlesh doondiashlesh@gmail.com

redis-py's IndexDefinition expects prefix to be a list or tuple.
Passing a bare string causes it to iterate character-by-character,
producing a malformed FT.CREATE PREFIX command that fails at runtime.

Wrap the prefix string in a list so the correct prefix is passed.

Fixes microsoft#13894

Signed-off-by: Doondi-Ashlesh <doondiashlesh@gmail.com>
@Doondi-Ashlesh Doondi-Ashlesh requested a review from a team as a code owner April 21, 2026 03:10
@moonbox3 moonbox3 added the python Pull requests for the Python Semantic Kernel label Apr 21, 2026
@github-actions github-actions Bot changed the title fix(python/redis): wrap IndexDefinition prefix in a list Python: fix(python/redis): wrap IndexDefinition prefix in a list Apr 21, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 95%

✓ Correctness

This is a correct and important bug fix. The IndexDefinition._append_prefix() method (redis-py 6.4.0) iterates over its prefix parameter with for p in prefix and reports len(prefix) as the prefix count. When a bare string like "my_collection:" was passed, len() returned the character count (e.g. 14) and the loop iterated over individual characters, producing a malformed index definition. Wrapping the string in a list ensures len(prefix) is 1 and the loop yields the single correct prefix string.

✓ Security Reliability

This is a correct bug fix. The IndexDefinition._append_prefix() method expects an iterable of prefix strings — it calls len(prefix) and then iterates over each element. When a bare string like "mycollection:" was passed, Python iterated over individual characters (e.g., "m", "y", "c", ..), producing a malformed index prefix definition. Wrapping the string in a list [f"{self.collection_name}:"] matches the expected type (the default parameter is prefix=[]) and ensures the full prefix string is treated as a single entry. No security or reliability issues introduced.

✗ Test Coverage

The change wraps the prefix parameter from a string to a list in IndexDefinition(prefix=[...]), which is a bug fix aligning with the redis-py API. However, the existing unit test test_create_index (line 294) uses an autouse mock that patches create_index entirely, so it never actually constructs an IndexDefinition or validates the prefix format. The test passes identically with both the old and new code, meaning there is no test that verifies this fix. There should be an assertion that the IndexDefinition is constructed with a list prefix.

✓ Design Approach

The change correctly fixes a genuine bug: IndexDefinition._append_prefix (redis 7.4.0, index_definition.py:43-49) calls len(prefix) and iterates over prefix with a for-loop. When passed a plain string like "mycollection:", this iterates over each character, producing a malformed PREFIX 12 m y c o l e c t i o n : Redis command instead of the intended PREFIX 1 mycollection:. Wrapping the string in a list is the correct fix. The test at line 302 in test_redis_store.py still passes a bare string prefix="test:" directly to IndexDefinition, which has the same bug, but that is outside the scope of this diff.

Flagged Issues

  • No test verifies the actual fix. test_create_index (test_redis_store.py:294) mocks create_index via the autouse fixture at line 83, so IndexDefinition is constructed but never inspected. The test passes with both prefix=string and prefix=[list]. Add a test (or update the existing one) that asserts create_index was called with an IndexDefinition whose prefix is a list.

Suggestions

  • test_redis_store.py:302 constructs IndexDefinition(prefix="test:", ...) with a bare string, which will also iterate character-by-character per the same _append_prefix logic. Consider fixing that test fixture as a follow-up to avoid a misleading test.

Automated review by Doondi-Ashlesh's agents

fields = _definition_to_redis_fields(self.definition, self.collection_type)
index_definition = IndexDefinition(
prefix=f"{self.collection_name}:", index_type=INDEX_TYPE_MAP[self.collection_type]
prefix=[f"{self.collection_name}:"], index_type=INDEX_TYPE_MAP[self.collection_type]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix is not covered by any test. test_create_index in test_redis_store.py:294 mocks create_index and never inspects the IndexDefinition argument. Please add a test that asserts create_index was called with a definition whose prefix is a list (e.g., via mock.call_args). Without this, the bug could regress silently.

…reate_index

The existing test_create_index called ensure_collection_exists() but never
inspected the IndexDefinition passed to create_index, so it passed even
when prefix was a bare string (the original bug).

- Parametrize test_create_index over hashset and json collection types.
- Assert that the IndexDefinition passed to create_index has args matching
  a reference built with a list prefix. A bare string prefix produces
  PREFIX <len(string)> <char> ... while a list produces PREFIX 1 <string>,
  so the args comparison catches the regression exactly.
- Fix test_create_index_manual which also used a bare string prefix="test:".
  Changed to prefix=["test:"] to match correct usage.

Signed-off-by: Doondi-Ashlesh <doondiashlesh@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Pull requests for the Python Semantic Kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: Bug: Redis connector sends malformed FT.CREATE PREFIX (one prefix per character of collection name)

2 participants