My filter.xml under ui.content looks like this -
<workspaceFilter version="1.0">
<filter root="/conf/myproject" mode="merge"/>
</workspaceFilter>
I have a subfolder under /conf/myproject containing some queries that I want to have mode="replace".
So I excluded that path from my filter.xml and added it as a separate filter as follows -
<workspaceFilter version="1.0">
<filter root="/conf/myproject" mode="merge">
<exclude pattern="/conf/myproject/settings/graphql/persistentQueries(/.*)?"/>
</filter
<filter root="/conf/myproject/settings/graphql/persistentQueries" mode="replace"/>
</workspaceFilter>
When I deploy using mvn clean install, I see old node properties for queries under /conf/myproject/settings/graphql/persistentQueries. The replace functionality doesn't seem to be working correctly.
What am I doing wrong?
Please note that when I place <filter root="/conf/myproject/settings/graphql/persistentQueries" mode="replace"/> at the very top of the file, everything seems to be working as expected.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
You're encountering a known behavior of Content Package Plugin's filter order evaluation during deployment in AEM.
The order of <filter> entries in filter.xml matters, especially when using different mode values like merge and replace.
AEM processes filters top to bottom.
If a merge filter appears before a replace filter (and covers the same or a parent path), the merge behavior will take precedence, and the replace will not override as expected — even with the <exclude>.
In your case, even though you've excluded the persistentQueries path in the merge filter, AEM still processes the parent node first, and the merge mode wins unless replace is declared earlier.
Move the replace filter to the top of your filter.xml, like so:
<workspaceFilter version="1.0"> <filter root="/conf/myproject/settings/graphql/persistentQueries" mode="replace"/> <filter root="/conf/myproject" mode="merge"> <exclude pattern="/conf/myproject/settings/graphql/persistentQueries(/.*)?"/> </filter> </workspaceFilter>
This ensures:
The replace operation happens before any merging.
The persistent queries node is fully replaced, removing old properties/nodes.
Thank you. So as per your code snippet above, considering I move the "replace" rule at the very top, do I still need to use an "exclude" rule?
or can I just use this?
<workspaceFilter version="1.0"> <filter root="/conf/myproject/settings/graphql/persistentQueries" mode="replace"/> <filter root="/conf/myproject" mode="merge"/> </workspaceFilter>
Views
Replies
Total Likes
Yes, if you place the replace filter at the top, you don’t need the <exclude>.
AEM processes filters in order, so the replace on /persistentQueries runs first and overrides everything there. The following merge on /conf/myproject won’t reprocess that path.
Views
Replies
Total Likes
Hi @ArchitAr2,
Did the shared solution help you out? If yes, kindly consider marking the answer as ‘correct’.
If you’re still facing any challenges, please feel free to continue the conversation here. We’re happy to support further.
Views
Replies
Total Likes
Hi @ArchitAr2 ,
The correct way is to put the replace filter at the top of the file. This ensures that AEM applies the replacement before processing any parent-level merge.
filter.xml:
<workspaceFilter version="1.0">
<filter root="/conf/myproject/settings/graphql/persistentQueries" mode="replace"/>
<filter root="/conf/myproject" mode="merge"/>
</workspaceFilter>
With this setup:
- The persistentQueries node is fully replaced.
- No need for any <exclude> rule.
- Everything else under /conf/myproject is merged as usual.
Regards,
Amit
Views
Replies
Total Likes