Why won’t my Shopify theme ZIP upload? The 11 errors that cause it
If Shopify refuses your theme ZIP, the cause is almost always a schema error inside one section file, not the archive itself. Shopify validates every {% schema %} block at upload time and rejects the whole theme when one setting is missing a label, carries a default it is not allowed to have, or contains a Liquid syntax error, and the message it returns names the setting id rather than the file.
Below is every upload failure we have recorded while generating and pushing Shopify themes at Themr, taken from the internal error catalog we keep, dated between April and July 2026. Each entry has the literal error string Shopify returns, the cause, and the fix.
What are the two kinds of theme upload failure?
They behave very differently, and knowing which one you have tells you where to look.
| Kind | What you see | Where the problem is |
|---|---|---|
| Rejected at upload | Shopify refuses the ZIP or drops a section file, with a message naming a setting id or a line number | A {% schema %} block or a Liquid syntax error in one section file |
| Uploads, then breaks | Theme installs fine, then the storefront prints a Liquid error inline or a page renders blank | A missing section file, an invalid form type, or a template referencing something that does not exist |
The second kind is more dangerous because nothing warns you. The theme appears in your theme library and looks installed. Shoppers see the error, not you.
Which errors stop a Shopify theme from uploading?
These eight reject the theme, or silently drop the offending section file so that the template referencing it fails.
| Error Shopify returns | Cause | Fix |
|---|---|---|
Invalid schema: setting with id="X" label is required |
A schema setting has an id and a type but no label |
Add "label" to every entry in settings, including settings nested inside blocks |
Invalid schema: setting with id="X" default must be a string or datasource access path |
A "type": "url" setting has a hardcoded path as its default, such as /pages/about |
Omit default entirely, or use a datasource path such as pages.about |
Invalid block 'X': setting with id="Y" default can’t be blank |
"default": "" on a setting inside a block schema. Shopify tolerates empty defaults at section level but not inside blocks |
Remove the default key, or give it a non-empty placeholder |
Invalid schema: setting with id="X" 'default' is not a valid attribute |
A default on an info-only setting. The header and paragraph types accept only content and an optional info |
Delete default and any stray id from header and paragraph settings |
config/settings_schema.json: Section 1: theme_name is too long (max 25 characters) |
A descriptive theme name in the theme_info block |
Keep theme_name, theme_version and theme_author at 25 characters or fewer each |
"sections/page.wishlist.liquid" contains illegal characters |
A dot in a section filename. Template filenames may use dots, section filenames may not | Rename to page-wishlist.liquid and update the "type" reference in the template JSON to match |
Liquid syntax error (line N): Unexpected character ' |
An apostrophe inside a single-quoted Liquid string, such as a default of 'You’re in.' |
Switch that string to double quotes, or rephrase without the contraction |
Liquid syntax error (line N): Expected end_of_string but found comma |
A filter piped inside a tag argument, such as image_tag: alt: title | escape, width: 800. The parser ends the expression at the comma |
Compute the value first with {%- assign alt = title | escape -%}, then pass the bare variable |
Three more schema mistakes reject in the same family: a range setting missing any of min, max or step, a select or radio missing its options array, and two settings sharing an id inside the same settings array. We first hit that group on 2026-05-28 and now lint for all four before anything reaches Shopify.
Why does one bad setting break a whole page?
Because the failure cascades. When Shopify rejects a section file, the file is simply not there, and any JSON template referring to it throws a second error that looks unrelated:
Section type 'manifesto' does not refer to an existing section file
Most people chase that second message. It is a symptom. Search your upload output for the earliest Invalid schema or Liquid syntax error line and fix that one instead.
Why did my theme upload but the storefront shows a Liquid error?
Three causes account for nearly all of them, and none is caught by the upload validator.
| Runtime error | Cause | Fix |
|---|---|---|
Error in tag 'section' - 'header' is not a valid section type |
layout/theme.liquid calls {% section 'header' %} but the file shipped under a different name |
Name the file to match the layout call. A custom header still has to live at sections/header.liquid |
Invalid form type "footer", must be one of ["product","contact","customer","cart",...] |
A newsletter block using {% form 'footer' %} or {% form section.id %}. Shopify accepts about 15 fixed form types and nothing else |
Use {% form 'customer' %} for any email capture, which is what Dawn does in its own footer |
templates/gift_card.liquid could not be deleted |
The gift card receipt template is missing. This one is a warning rather than a failure | Include a minimal templates/gift_card.liquid. Shopify’s default version is fine |
The form type error is the meanest of the three. It renders as plain text inside the page where the signup form should be, so the first person to notice it is usually a customer.
What about the ZIP file itself?
Archive-level problems are real but much rarer than schema problems. Two things to confirm before you go hunting through Liquid:
- The folders must sit at the root of the archive. Opening the ZIP should show
layout/,sections/,templates/,config/andassets/directly. If it shows a single folder that contains all of those, you zipped the folder instead of its contents, and Shopify will not recognise it as a theme. - The archive has to be under 50 MB. Oversized theme ZIPs are almost always full of uncompressed hero images. Those belong on Shopify’s CDN, through the Files section or an
image_pickersetting, rather than baked intoassets/.
How do I check a theme for these errors before uploading?
Run both of these. They catch different things, which is the whole point.
shopify theme checkcatches the static problems: hardcoded routes, missing assets, image tags without width and height. It does not catch everything the upload validator does.shopify theme push --unpublishedis the real test. It runs Shopify’s own upload validation and prints the exact rejection messages listed above, without touching your live theme.
The trap worth knowing: a local Liquid preview will not catch schema errors. Local rendering engines strip the {% schema %} block before rendering, so a theme missing a label on every setting previews perfectly and then fails on push. We lost real time to that before writing a schema linter of our own. If you are previewing locally, you are testing your markup, not your schema.
Where this list comes from
These are not hypothetical errors. Every entry above is recorded in the error catalog we keep while building Themr, an AI Shopify theme generator, along with the date it first appeared and the fix that closed it. The oldest entry here is 2026-04-30 and the newest is 2026-07-08. Every theme Themr produces is validated against all of them before you download it, which is the entire reason the catalog exists.
If you would rather not debug schema JSON at all, you can start from one of the 12 free starter themes, which are already validated, or read how a generated theme compares with the alternatives in AI theme versus headless and the honest case for and against Dawn. If the theme you are uploading is a replacement for one that is already live, here is exactly what a theme switch does and does not reset. Once it is installed, the next things worth checking are whether it scrolls sideways at 390px and whether the homepage renders at all, neither of which upload validation tests for. One more that upload validation does flag, at error severity, but that plenty of themes ship anyway: a locale key the theme references and no file defines, which prints "Translation missing" on the storefront.
Frequently asked questions
Why does Shopify say "Invalid schema" when I upload my theme?
Shopify validates every {% schema %} block at upload. The four most common triggers are a setting with no "label", a "type": "url" setting with a hardcoded path as its default, an empty string default on a setting inside a block, and a "default" key on a header or paragraph info setting. The message names the setting id, so search your section files for that id to find the file.
What does "Section type X does not refer to an existing section file" mean?
It means Shopify rejected that section file earlier in the same upload, so the JSON template pointing at it now has nothing to render. It is a symptom rather than the cause. Scroll up in the upload output to the first Invalid schema or Liquid syntax error line and fix that one instead.
My theme uploaded fine but the storefront shows a Liquid error. Why?
Upload validation checks schema and Liquid syntax, not whether every reference resolves at render time. The two usual causes are layout/theme.liquid calling a section file that shipped under a different name, and a newsletter form using an invented form type. Shopify accepts about 15 built-in form types and nothing else, so use {% form "customer" %} for email capture.
Is there a size limit on a Shopify theme ZIP?
Yes, 50 MB. Themes that exceed it are usually carrying uncompressed hero images in the assets folder. Serve large images from Shopify’s CDN using the Files section or an image_picker setting instead of bundling them into the theme.
How do I test a Shopify theme before uploading it to my live store?
Run shopify theme check for static issues, then shopify theme push --unpublished. The second one runs Shopify’s real upload validation and returns the exact rejection messages while leaving your published theme untouched.
Why does a theme that previews perfectly on my machine fail when I upload it?
Local Liquid renderers strip the {% schema %} block before rendering, so schema errors are invisible in local preview. A theme missing a required label on every setting will preview flawlessly and still be rejected on push. Local preview tests your markup, not your schema.
Generate a theme that looks like your brand
A complete Shopify 2.0 theme with conversion features built in, ready in minutes. No credit card required.
Generate my theme freeNo Shopify store yet? Start one here, then bring the theme. Themr may earn a commission if you start a paid plan; it does not change what you pay.