Skip to main content

Command Palette

Search for a command to run...

Sitecore Serialization: "First Match Wins"

A Tiny Detail That Can Mess With Your Day

Updated
3 min read
Sitecore Serialization: "First Match Wins"

#sitecore #sitecoreAI #xmcloud #serialization #dailywork

When I recently reviewed the serialization modules of a customer project we had taken over,
I stumbled upon something that wasn’t obvious at first glance —
but explained a few weird effects we’d seen during deployments.

Short version:

Serialization rules are evaluated top to bottom.
First match wins.

Sounds obvious, but in practice it’s surprisingly easy to overlook.


A quick refresher

Sitecore Content Serialization (SCS) turns Sitecore items into versionable, shareable files — and that really pays off during deployments. SCS takes care of moving those items into the target environment, which keeps deployments consistent and pleasantly predictable.

Which items become part of your source-controlled configuration and how they should behave during deployments, is defined in your module.json files.

Every *.module.json follows the same basic structure:

  • path → where your module starts

  • scope → how deep it goes (ItemOnly, ItemAndDescendants, Descendants, …)

  • allowedPushOperations → what’s allowed when pushing (CreateOnly, CreateAndUpdate, etc.…)

  • rules → exceptions or overrides inside that module


In the client project, the module had:

  • a very broad rule at the top (/Settings)

  • a more specific rule below (/Settings/Site Grouping)

  • different allowedPushOperations on each

Something like this:

{
  "items": {
    "path": "/sitecore/content/MyProject",
    "scope": "ItemAndDescendants",
    "allowedPushOperations": "CreateUpdateAndDelete",
    "rules": [
      {
        "path": "/Settings",
        "scope": "ItemAndDescendants",
        "allowedPushOperations": "CreateAndUpdate"
      },
...
      {
        "path": "/Settings/Site Grouping",
        "scope": "ItemAndDescendants",
        "allowedPushOperations": "CreateOnly"
      }
    ]
  }
}

The result?
The broad /Settings rule matches everything underneath — including /Settings/Site Grouping.
Which means: the more specific “CreateOnly” rule never gets a chance to apply.

**And that’s exactly what we saw: the Site Grouping item was still being updated during deployments.
Definitely not something you want happening in higher environments.
**

How to fix it

Luckily, the fix is straightforward:
put the more specific rule first, then the broader one.

Serialization processes rules from top to bottom, so the specific one needs to get its turn before the general one catches everything.

In our case, swapping the order is all it takes:

"rules": [
  {
    "path": "/Settings/Site Grouping",
    "scope": "ItemAndDescendants",
    "allowedPushOperations": "CreateOnly"
  },
...
  {
    "path": "/Settings",
    "scope": "ItemAndDescendants",
    "allowedPushOperations": "CreateAndUpdate"
  }
]

Now the CreateOnly rule actually applies to the Site Grouping item - exactly as intended.


Extra Tip: How to verify what actually happens

If you want to double-check which rule Serialization is actually using for an item, the CLI can tell you.
The ser explain command shows:

  • which module included the item

  • which rule matched

  • and which allowedPushOperations were applied

dotnet sitecore ser explain -p "/sitecore/content/.../Settings/Site Grouping"

Super handy when something behaves differently than expected and debugging mysterious “why is this still updating?” situations.


Wrap-up

It’s a tiny detail, but it can have a surprisingly big impact.

One misplaced line can silently break your configuration and update items you never meant to touch.
Understanding how Sitecore reads these rules - first come, first served -
can save you a whole afternoon of head-scratching.