fix(redis): escape all RediSearch special chars in metadata, not just -#6610
fix(redis): escape all RediSearch special chars in metadata, not just -#6610iruzen-dono wants to merge 1 commit into
Conversation
Redis Search reserves many characters as operators/syntax:
,.<>{}[]"':;!@#$%^&*()-+=~
The current escapeSpecialChars only escapes '-', so metadata containing
any other special character (e.g. ':', '"') causes JSON.parse failures
when retrieved from the vector store.
Fix by escaping all reserved characters on write and un-escaping them
on read.
Fixes FlowiseAI#6598
There was a problem hiding this comment.
Code Review
This pull request expands the Redis utility functions to escape and unescape a comprehensive list of RediSearch special characters, rather than just the hyphen. The review feedback correctly identifies a redundant hyphen in the regular expression used for unescaping and provides a cleaner regex suggestion.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
||
| export const unEscapeSpecialChars = (str: string) => { | ||
| return str.replaceAll('\\-', '-') | ||
| return str.replace(/\\([-,.<>{}[\]"':;!@#$%^&*()\-+=~])/g, '$1') |
There was a problem hiding this comment.
The character class contains a redundant escaped hyphen \- in addition to the leading hyphen -. We can simplify the regex by removing the redundant hyphen.
| return str.replace(/\\([-,.<>{}[\]"':;!@#$%^&*()\-+=~])/g, '$1') | |
| return str.replace(/\\([-,.<>{}[\]"':;!@#$%^&*()+=~])/g, '$1') |
There was a problem hiding this comment.
Pull request overview
This PR fixes Redis vector store metadata retrieval failures by expanding RediSearch escaping/unescaping beyond just -, so metadata containing other reserved characters (e.g. : or ") can be safely round-tripped and parsed as JSON.
Changes:
- Expand
escapeSpecialCharsto escape the full RediSearch reserved character set used by queries/tag values. - Update
unEscapeSpecialCharsto reverse all escaped reserved characters via a single regex.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export const unEscapeSpecialChars = (str: string) => { | ||
| return str.replaceAll('\\-', '-') | ||
| return str.replace(/\\([-,.<>{}[\]"':;!@#$%^&*()\-+=~])/g, '$1') | ||
| } |
| .replaceAll(')', '\\)') | ||
| .replaceAll('+', '\\+') | ||
| .replaceAll('=', '\\=') | ||
| .replaceAll('~', '\\~') |
There was a problem hiding this comment.
Good catch. I think we’re still missing one Redis query separator: |.
Since buildQuery uses | as the OR operator to join metadata filters, a literal value like foo | bar will be incorrectly parsed as two separate alternatives instead of a single metadata value. As noted in the Redis documentation, | is a special character that needs to be escaped in tag filters.
Could you, please, update both escapeSpecialChars and unEscapeSpecialChars to include |, and add a regression test for a metadata filter value containing a pipe? I think it'll be really useful!
What
Redis vector store
escapeSpecialCharsonly escapes the-character, but Redis Search reserves many more characters as operators/syntax:,.<>{}[]"':;!@#$%^&*()-+=~When document metadata contains any of these unescaped characters (e.g.
:,"), JSON.parse fails on retrieval.Fix
escapeSpecialChars: now escapes all 26 RediSearch reserved charactersunEscapeSpecialChars: now reverses all 26 escaped characters (single regex)Reproduction
References
Closes #6598