Skip to content

fix (redis): unEscapeSpecialChars now handles all RediSearch special c…#6598#6601

Open
eajajhossain wants to merge 1 commit into
FlowiseAI:mainfrom
eajajhossain:bugfix/redis-unescape-special-chars
Open

fix (redis): unEscapeSpecialChars now handles all RediSearch special c…#6598#6601
eajajhossain wants to merge 1 commit into
FlowiseAI:mainfrom
eajajhossain:bugfix/redis-unescape-special-chars

Conversation

@eajajhossain

@eajajhossain eajajhossain commented Jul 6, 2026

Copy link
Copy Markdown

issue - 6598
Title:
fix(redis): unEscapeSpecialChars now handles all RediSearch special charaers

Description:

Bug:
Similarity search in the Retrieval Playground fails with SyntaxError: Expected property name or '}' in JSON when a document's metadata contains RediSearch special characters such as : or " (e.g. gs://bucket:path/file.pdf).

Root Cause:
@langchain/redis` stores metadata as escapeSpecialChars(JSON.stringify(metadata)), escaping -, :, and " in the full JSON string. On retrieval, Flowise calls unEscapeSpecialChars() before JSON.parse(). The old implementation only removed -, leaving " and : in the string, producing invalid JSON.

Fix:
Extended unEscapeSpecialChars regex in utils.ts to cover all RediSearch-reserved characters — matching the full set that RediSearch may escape.

Files Changed:
packages/components/nodes/vectorstores/Redis/utils.ts - fixed unEscapeSpecialChars
packages/components/nodes/vectorstores/Redis/utils.test.ts - added regression tests (15 tests, all passing)

Copilot AI review requested due to automatic review settings July 6, 2026 11:49

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request updates the Redis vector store utility functions to escape and unescape all RediSearch special characters instead of only hyphens, and introduces a comprehensive test suite. Feedback on the changes highlights a critical issue where unescaping all special characters (especially backslashes) on the entire JSON string can corrupt valid JSON escape sequences, potentially causing JSON parsing to fail. It is recommended to only unescape -, :, and " which are the characters escaped by @langchain/redis. Additionally, it is suggested to escape other characters like |, ?, and / to prevent query injection, and to add a regression test case for metadata containing backslashes (such as Windows file paths).

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')

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.

critical

Unescaping all RediSearch special characters (especially \\) on the entire JSON string will corrupt valid JSON escape sequences (such as \\\\ representing a single backslash in a path or string value). Since @langchain/redis only escapes -, :, and " when storing metadata, unEscapeSpecialChars should only unescape these three characters to avoid corrupting the JSON structure and causing JSON.parse to fail on metadata containing backslashes (e.g., Windows file paths).

Suggested change
return str.replace(/\\([,.<>{}[\]"':;!@#$%^&*()\-+=~\\])/g, '$1')
return str.replace(/\\([-:"])/g, '$1')

*/
export const escapeSpecialChars = (str: string) => {
return str.replaceAll('-', '\\-')
return str.replace(/([,.<>{}[\]"':;!@#$%^&*()\-+=~\\])/g, '\\$1')

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.

high

In particular, unescaped | characters in filter values can be interpreted as OR operators, which can lead to query injection or filter bypasses. We should include |, ?, and / in the list of escaped characters to ensure robust query execution and security.

    return str.replace(/([,.\u003c\u003e{}[\\]\"':;!@#$%^\u0026*()\\-+=~\\\\|?\\/])/g, '\\$1')

Comment on lines +176 to +181
test('round-trips plain metadata with no special chars (sanity check)', () => {
const original = { source: 'simple_file.pdf', page: 4 }
const stored = simulateUpsert(original)
const retrieved = simulateRetrieval(stored)
expect(retrieved).toEqual(original)
})

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.

medium

We should add a regression test case to verify that metadata containing backslashes (such as Windows file paths) can be successfully round-tripped without causing JSON parsing errors.

    test('round-trips plain metadata with no special chars (sanity check)', () => {
        const original = { source: 'simple_file.pdf', page: 4 }
        const stored = simulateUpsert(original)
        const retrieved = simulateRetrieval(stored)
        expect(retrieved).toEqual(original)
    })

    test('round-trips metadata containing backslashes in a value', () => {
        const original = { path: 'C:\\\\path\\\\to\\\\file', page: 5 }
        const stored = simulateUpsert(original)
        const retrieved = simulateRetrieval(stored)
        expect(retrieved).toEqual(original)
    })

Copilot AI left a comment

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.

Pull request overview

This PR updates the Redis vectorstore utilities to properly escape/unescape a broader set of RediSearch operator/delimiter characters, preventing malformed metadata round-trips (notably when JSON-serialized metadata includes reserved characters), and adds a dedicated test suite to lock in the behavior.

Changes:

  • Expand escapeSpecialChars to escape a full set of RediSearch-reserved characters (instead of only -).
  • Expand unEscapeSpecialChars to reverse those escapes so metadata JSON can be parsed correctly on retrieval.
  • Add utils.test.ts with unit tests plus a production-flow regression round-trip test.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
packages/components/nodes/vectorstores/Redis/utils.ts Broadens RediSearch escaping/unescaping logic used by query-building and metadata retrieval.
packages/components/nodes/vectorstores/Redis/utils.test.ts Adds coverage for escaping/unescaping and a regression test simulating the real storage/retrieval flow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6 to +10
* so they must be escaped when stored as metadata values:
* , . < > { } [ ] " ' : ; ! @ # $ % ^ & * ( ) - + = ~ \
*/
export const escapeSpecialChars = (str: string) => {
return str.replaceAll('-', '\\-')
return str.replace(/([,.<>{}[\]"':;!@#$%^&*()\-+=~\\])/g, '\\$1')
Comment on lines 30 to +31
export const unEscapeSpecialChars = (str: string) => {
return str.replaceAll('\\-', '-')
return str.replace(/\\([,.<>{}[\]"':;!@#$%^&*()\-+=~\\])/g, '$1')
Comment on lines +40 to +44
'+',
'=',
'~',
'\\'
]
Comment on lines +96 to +100
'+',
'=',
'~',
'\\'
]
@eajajhossain eajajhossain changed the title fix (redis): unEscapeSpecialChars now handles all RediSearch special c… fix (redis): unEscapeSpecialChars now handles all RediSearch special c…#6598 Jul 6, 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.

2 participants