# Troubleshooting

> Common symptoms and error codes when integrating TryYourSize, with their cause and fix. Search this page for the code you see.

Source: https://docs.tryyoursize.com/guides/troubleshooting/

Search this page (or the whole site with <kbd>/</kbd>) for the symptom or the error code you see. Each entry says what causes it and how to fix it. Still stuck? Write to support@tryyoursize.com with the **request ID** (`X-Request-ID` header, or `requestId` / `request_id` on SDK errors).

## The element does not appear

The size guide, button or inline element never shows on the page.

1. **The visitor is in the A/B holdout.** With an experiment running, 10–50 % of visitors see nothing at all, by design. Check with `await tys.experiment()` (`arm: "holdout"`), or stop the experiment in Studio → Results while testing.
2. **The mount target does not exist yet.** `mount("#size-guide")` throws [`mount_not_found`](https://docs.tryyoursize.com/sdk/errors.md#mount_not_found) when the selector matches nothing. Mount after the container is in the page.
3. **The page's origin is not registered** for the key's mode. Add it in Studio → Settings → Stores → Allowed sites (`https://` and no path; `http://localhost` works in test mode without registering).
4. **A Content Security Policy blocks us.** Allow `script-src https://js.tryyoursize.com` and `frame-src https://embed.tryyoursize.com`. The browser console shows the blocked URL.

## window_unreachable or a loaderror event

Our window did not load or connect within 15 seconds. Same causes as above (origin, CSP), or a network filter or ad blocker blocking `tryyoursize.com`. Listen to `loaderror` and fall back to your own size chart. See [`window_unreachable`](https://docs.tryyoursize.com/sdk/errors.md#window_unreachable).

## secret_key_in_browser or secret_key_in_app

A secret key (`sk_…`) or restricted key (`rk_…`) reached a browser or an app. Use the publishable key there, and [roll the secret key](https://docs.tryyoursize.com/get-started/keys-and-modes.md) in Studio if the code was deployed.

## app_not_allowed in an iOS or Android app

The app is not registered for the key. Add `ios-app://<bundle id>` or `android-app://<package>` (lower case) to the allowed sites for **test mode**. `tys.appOrigin` prints the exact value. Live mode for apps is coming soon.

## The size guide always says "Size guide"

The shopper is not connected to TryYourSize on your site (`status: "signed_out"`). That is expected until they sign in once in our window. Each site (origin) has its own connection: a shopper connected on `staging.brand.com` is not connected on `www.brand.com`.

## The status is always unavailable

The shopper is connected, but there is no size for this product yet:

- The product has **no published garment** in TryYourSize (live mode answers published versions only; test mode answers drafts). Publish it in Studio or with [`garments.publish()`](https://docs.tryyoursize.com/reference/node/garments-publish.md).
- The `product` you pass is not the SKU or ID synced to TryYourSize. `tys.products.retrieve("<your value>")` on your server tells you.
- The shopper has not tried this garment on yet. Page views never start a simulation; the shopper starts it with "See it on you". When it finishes you get another `recommendation` event.
- The visitor is in the A/B holdout: the holdout always gets `unavailable`.

## The size is not in my size labels

Sizes come back through the product's **size map** (Studio size → your label). Without an entry, you get the Studio label. Map them in Studio, or with [`sizeMap.save()`](https://docs.tryyoursize.com/reference/node/products-size-map-save.md). `unmapped_shop_values` lists your variant values without a Studio size.

## 401 unauthorized from the API

The key is missing, mistyped or revoked, or a publishable key was used on the server. Server calls need `Authorization: Bearer sk_…` (or `rk_…`). See [`unauthorized`](https://docs.tryyoursize.com/api/errors.md#unauthorized).

## 403 forbidden from the API

A restricted key lacks the scope (each operation lists its **Key scopes**), or a test key reads live data (or the other way round). See [`forbidden`](https://docs.tryyoursize.com/api/errors.md#forbidden).

## handle_expired, handle_invalid or handle_mode_mismatch

Recommendation handles last an hour and belong to one mode. Ask the browser for a fresh one with `tys.recommendationHandle()`; use a test secret key with a handle from a test publishable key. A shopper who disconnected your store gets `handle_invalid`. See [`handle_expired`](https://docs.tryyoursize.com/api/errors.md#handle_expired).

## 429 rate_limited

Too many requests. Wait for the `Retry-After` seconds and retry with backoff; the SDKs do this for you. With an `Idempotency-Key`, a retried `POST` is safe. See [Rate limits](https://docs.tryyoursize.com/guides/rate-limits.md).

## 409 idempotency_key_in_use or 422 idempotency_key_reused

`idempotency_key_in_use`: the first request with this key is still running; retry shortly. `idempotency_key_reused`: you sent the same key with a different body. Use one key per distinct request. See [Idempotency](https://docs.tryyoursize.com/guides/idempotency.md).

## A webhook signature does not verify

Almost always the body was parsed and re-serialized before verification. Verify the **raw** bytes: with Express use `express.raw({ type: "application/json" })`; in Flask use `request.get_data()`. Check you use the endpoint's own `whsec_…` secret (test and live endpoints differ), and that the server clock is right (5 minutes of tolerance). See [Webhooks](https://docs.tryyoursize.com/guides/webhooks.md#verify-the-signature).

## Orders do not show up in Results

Results count orders sent with [`POST /v1/orders`](https://docs.tryyoursize.com/guides/outcomes.md) in **live** mode. For the A/B comparison each order needs the arm: send `visitor_id` (from `tys.experiment()` in the browser, saved with the cart) or `experiment_arm`. An order without either is counted outside the experiment.

## The shopper picked a size, but my picker changed it

Preselect only until the shopper chooses: keep a "touched" flag and never overwrite their choice when a later `recommendation` event arrives. See [Preselect the recommended size](https://docs.tryyoursize.com/guides/recommendation-event.md).
