D
P
0

Shopify & Liquid

Deleted a Section From Shopify `templates/index.json` but It Keeps Coming Back? `order` and `sections` Are Coupled

July 5, 2026·4 min read
Deleted a Section From Shopify `templates/index.json` but It Keeps Coming Back? `order` and `sections` Are Coupled

I was tidying up the homepage of a client's Shopify store: swap an old hero for a new one. A trivial task, or so I thought. I opened templates/index.json, found the old hero's id in the order array, deleted it, pushed. The CLI reported success. I opened the live page to verify, and what I saw made me squint: the old hero and the new hero were both rendering, stacked. Not one replacing the other, but sitting side by side.

My first instinct was a bad one: I assumed a cache issue, or that the push had not really landed. I pushed again, success again, same result. So I did the thing I should have done from the start. I re-pulled the template and reopened the file. And there the culprit was: the old hero id I had deleted was back in the order array. As if my edit had been silently undone by the server.

Why this happens

A Shopify JSON template is not one flat list. It has two coupled structures: an order array that dictates render order, and a sections object that holds each section's definition (its type and settings). The two must stay consistent. And here is the trap: if a section's definition still exists inside the sections object, a Shopify push auto-restores its id into the order array.

So what I had done was half the job. I had only pulled the id hero_jVaWmY out of the order array, but its definition block was still intact in the sections object. To Shopify, that was an invalid state: a section that is defined but has no position. Instead of treating it as intentionally removed, Shopify "repaired" it by inserting the id back into order. Every time I pushed, that definition re-seeded itself. Deleting only the order entry was never going to be enough.

Once that clicked, everything made sense. Not a cache, not a failed push. I had simply deleted half of a pair that must not be split, then wondered why the other half kept pulling it back.

The fix

The fix is to delete in both places at once. Inside templates/index.json, remove the hero id from the order array AND delete its entire definition block from the sections object.

{
  "sections": {
    "hero_jVaWmY": {
      "type": "hero-banner",
      "settings": { }
    }
  },
  "order": [
    "hero_jVaWmY"
  ]
}

What I did: drop the string "hero_jVaWmY" from the order array, then also delete the entire "hero_jVaWmY": { ... } entry from the sections object. After that, validate the JSON first, make sure there is no dangling comma or unbalanced brace, then push:

shopify theme push --path=<theme-dir>

The step you must not skip: verify. A successful push is not proof. I re-pulled the template and counted how many times the id still appeared:

grep -c hero_jVaWmY templates/index.json

If the result is 0, the section is genuinely gone from both structures. If it is not, I missed one place. That zero is the only proof I trust, not the CLI's "success" banner.

Why re-pulling is mandatory

What changed me on this case was the habit of re-pulling after a push, not just eyeballing the live page. The live page can lie because of rendering and cache. The pulled file shows the real state the server holds. If an id I thought was dead turns out to be back in that file, I immediately know the sections object is still holding its definition.

This trap also explained something else that used to confuse me: sections I had "disabled" via the theme editor kept quietly accumulating. Disabling one or pulling it out of the order does not delete its definition. That definition persists in the sections object, ready to re-seed itself. So now I routinely prune definitions I no longer use, not just tidy the order.

The takeaway

In a Shopify JSON template, order and sections are a pair that must not be split. Deleting a section means pulling its id out of order AND deleting its definition from sections, both, in a single edit. Do only one and the next push will reunite them in a way you did not intend. And do not trust the "success" banner: re-pull, grep -c the id, and confirm the number is zero before you call it done. Since then, I have stopped pushing on repeat and hoping, and started treating the JSON template as the coupled structure it actually is.