Envie
Guides

Troubleshooting

The symptoms we actually see, what each one means, and the fix — check here before writing to support.

Symptom-first list of the problems integrators actually hit. Every fix links the page that explains the mechanism.

Storefront

The save button renders nothing

An inert <envie-button> tag means the components bundle never loaded — the app embed is off. Theme editor → App embeds → Envie → enable, then reload. The app's home page in the Shopify admin verifies this for you ("Verified" badge on step 1).

If the embed is on and the element is still dead, check the browser console for a blocked script (a CSP or an aggressive performance app can strip deferred scripts).

The button renders but clicking does nothing (or flips back)

The optimistic toggle reverted — the API rejected the save. Listen for the reason:

document.addEventListener("envie:error", (event) => console.log(event.detail.message));

Usual causes, in order: missing handle on a hand-written tag (validation) · guest saves disabled on the shop (guest-disabled) · free-plan cap reached (plan-limit).

Browser console shows a CORS error (headless)

Your storefront's origin isn't declared. Envie → Developers → Headless origins — add the exact origin (https://shop.example.com, no path, no trailing slash). Takes effect within a minute. Auth reference.

401 invalid-signature from a Liquid theme

Theme code is calling api.getenvie.com directly. From Liquid, requests must go through the app proxy on the shop's own domain (/apps/envie/…) — only that path carries Shopify's signature. createEnvie() with no options does this for you. Details.

Identity

The wishlist didn't follow the shopper after login

  • Liquid: the merge runs on the first page view after login — check the shopper actually loaded a page with the embed active. The merge is once per (browser, customer); a shopper who cleared localStorage gets a fresh guest list by design.
  • Headless: identify() must run server-side with the shopper's envie:aid from their browser. The merge guide has the full flow; the usual bug is a hardcoded or missing anonymousId.

identify-forbidden in the console

identify() was called from browser code in public mode. It only works server-side — why and how.

Server-side

Webhook signatures never verify

Nine times out of ten: verifying against re-serialized JSON instead of the raw request bytes. Keep the raw body for the HMAC — complete working example in the webhooks guide. Also check you're using the endpoint's own secret (each endpoint has its own, shown at creation).

Import finished but items are "missing"

Open the dry-run report (resultUrl): rows that resolve to no customer are skipped and listed with line numbers — deleted customers and guest-only rows are the common bulk. imported: 0 on a re-run means everything was already there (imports are idempotent). Import rules.

429s under normal load

You're polling something that should be pushed. Budget math and the fixes: rate-limited.

Playground

Every playground request returns 401

The playground sends exactly what you give it: private endpoints need an env_sk_… key in the Authorization field; storefront endpoints in public mode need X-Envie-Shop + X-Envie-Public-Key. And anything you paste into a browser should be a key you can rotate.

Still stuck?

Support — include the requestId from the error response and you'll skip a round trip.

On this page