Describe the Bug
We found an issue in RedirectsProxy.getExistsRedirect() where valid regex redirect patterns returned by the redirects GraphQL query are not matched correctly.
In our case, the redirect rule is present in the GraphQL response, but the proxy still logs skipped (redirect does not exist) and no redirect is applied.
Based on Sitecore documentation, this appears to be a valid configuration rather than a misuse of the feature. Sitecore documents that redirect patterns are treated as regular expressions when they start with ^ and end with $, and provides examples such as ^/blogs/blogs-november/$ and ^/ab[cd]/$. The same documentation also states that matching is case-insensitive and that patterns must begin with /.
Observed behavior
A redirect is successfully returned by the GraphQL response:
{
"pattern": "^/cmmc$",
"target": "/insights/cmmc-readiness-assessment#assessment",
"redirectType": "REDIRECT_301",
"isQueryStringPreserved": true,
"isLanguagePreserved": false,
"locale": ""
}
The incoming request is:
/cmmc
The proxy logs show that redirect data is fetched correctly, but the redirect is not matched:
content-sdk:redirects redirects proxy start: { pathname: '/cmmc', language: 'en', hostname: 'localhost:3000' }
content-sdk:redirects request: ...
content-sdk:redirects response in ...ms: { site: { siteInfo: { redirects: [Array] } } }
content-sdk:redirects skipped (redirect does not exist)
Why this looks like an SDK bug
According to the documentation, regex redirect patterns such as ^/blogs/blogs-november/$ and ^/ab[cd]/$ are valid supported scenarios. The pattern ^/cmmc$ follows the same documented format, so it should be considered a valid redirect rule.
However, in RedirectsProxy.getExistsRedirect(), the regex normalization logic appears to modify the incoming pattern before matching. In particular, the code prepends ^ before additional normalization:
redirect.pattern = escapeNonSpecialQuestionMarks(
'^' + redirect.pattern.replace(new RegExp(`^[^]?/${locale}/`, 'gi'), '')
);
If the original pattern is already anchored, for example:
^/cmmc$
this can produce:
^^/cmmc$
Later cleanup logic appears to assume a cleaner input shape and may not fully normalize this case correctly:
redirect.pattern = `/^\/${redirect.pattern
.replace(/^\/|\/$/g, '')
.replace(/^\^\/|\/\$$/g, '')
.replace(/^\^|\$$/g, '')
.replace(/\$\/gi$/g, '')}[\/]?$/i`;
As a result, the final regex used for matching may no longer represent the original valid pattern, causing getExistsRedirect() to return undefined.
To Reproduce
- Configure a redirect rule that is returned by the redirects GraphQL query with:
- pattern:
^/cmmc$
- target:
/insights/cmmc-readiness-assessment#assessment
- redirectType:
REDIRECT_301
- isQueryStringPreserved:
true
- isLanguagePreserved:
false
- Send a request to:
/cmmc
- Observe that:
the redirect is present in the GraphQL response
the proxy logs skipped (redirect does not exist)
no redirect response is generated
Expected Behavior
The redirect rule with pattern ^/cmmc$ should match the incoming request /cmmc and return a 301 redirect to:
/insights/cmmc-readiness-assessment#assessment
This expectation is consistent with the documented regex redirect behavior in Sitecore, where patterns starting with ^ and ending with $ are valid regex rules.
Possible Fix
It looks like the regex normalization logic should avoid blindly prepending ^ when the pattern is already anchored, or otherwise make the downstream normalization robust enough to preserve already valid regex patterns returned by user/graphql.
Provide environment information
- Sitecore Version: Sitecore AI
- Content SDK Version: 2.0.2
Describe the Bug
We found an issue in
RedirectsProxy.getExistsRedirect()where valid regex redirect patterns returned by the redirects GraphQL query are not matched correctly.In our case, the redirect rule is present in the GraphQL response, but the proxy still logs
skipped (redirect does not exist)and no redirect is applied.Based on Sitecore documentation, this appears to be a valid configuration rather than a misuse of the feature. Sitecore documents that redirect patterns are treated as regular expressions when they start with
^and end with$, and provides examples such as^/blogs/blogs-november/$and^/ab[cd]/$. The same documentation also states that matching is case-insensitive and that patterns must begin with/.Observed behavior
A redirect is successfully returned by the GraphQL response:
The incoming request is:
/cmmcThe proxy logs show that redirect data is fetched correctly, but the redirect is not matched:
Why this looks like an SDK bug
According to the documentation, regex redirect patterns such as
^/blogs/blogs-november/$and^/ab[cd]/$are valid supported scenarios. The pattern^/cmmc$follows the same documented format, so it should be considered a valid redirect rule.However, in
RedirectsProxy.getExistsRedirect(), the regex normalization logic appears to modify the incoming pattern before matching. In particular, the code prepends^before additional normalization:If the original pattern is already anchored, for example:
^/cmmc$this can produce:
^^/cmmc$Later cleanup logic appears to assume a cleaner input shape and may not fully normalize this case correctly:
As a result, the final regex used for matching may no longer represent the original valid pattern, causing
getExistsRedirect()to returnundefined.To Reproduce
^/cmmc$/insights/cmmc-readiness-assessment#assessmentREDIRECT_301truefalse/cmmcthe redirect is present in the GraphQL response
the proxy logs
skipped (redirect does not exist)no redirect response is generated
Expected Behavior
The redirect rule with pattern
^/cmmc$should match the incoming request/cmmcand return a 301 redirect to:/insights/cmmc-readiness-assessment#assessmentThis expectation is consistent with the documented regex redirect behavior in Sitecore, where patterns starting with
^and ending with$are valid regex rules.Possible Fix
It looks like the regex normalization logic should avoid blindly prepending
^when the pattern is already anchored, or otherwise make the downstream normalization robust enough to preserve already valid regex patterns returned by user/graphql.Provide environment information