> ## Documentation Index
> Fetch the complete documentation index at: https://developer.cashbackhive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Fix common Cashback Hive SDK integration problems: the script not initialising, 403 origin errors, blocked sign-in popups, empty offers and CSP issues.

Turn on [debug logging](https://developer.cashbackhive.com/guides/local-development.md#debug-logging) with `data-debug` while you investigate — the SDK will explain what it's doing in the console.

## `cbh:ready` never fires

> [accordion] The script tag has no data-key
>
> Without `data-key` the SDK loads but doesn't initialise, and `cbh:ready` only fires after initialisation. Either add `data-key` or call `CashbackHive.init({ key })` yourself.
>
> Check: `window.CashbackHive` exists but `window.CashbackHive.initialized` is `false`.

> [accordion] Your listener was added after the event fired
>
> `cbh:ready` fires once. If your code runs after that (a lazily loaded component, a client-side route change, a tag that executes late), it misses the event. Check `window.CashbackHive?.initialized` first, and only add the listener if it's `false`. See [Lifecycle](https://developer.cashbackhive.com/concepts/lifecycle.md#initialized-property).

> [accordion] The script didn't load
>
> Check the Network tab for `sdk.js`. A blocked request is usually a CSP violation (look for a `Refused to load the script` console error), an ad blocker, or a typo in the URL. See [Content Security Policy](https://developer.cashbackhive.com/guides/content-security-policy.md).

> [accordion] The script was injected without data-key set
>
> When injecting the tag from JavaScript, set `script.dataset.key` **before** `appendChild`. The SDK reads attributes synchronously when it executes.

## `offers.list()` rejects with 403

The current origin isn't in the property's allowed origins. The origin includes the scheme and port, so `http://localhost:3000`, `http://localhost:5173`, `https://example.com` and `https://www.example.com` are all different. Add the exact origin in the publisher portal.

Check: `location.origin` in the console shows the origin you need to allow.

## `offers.list()` rejects with 401

The publishable key is wrong or has been rotated. Compare `document.querySelector('script[src*="cashbackhive"]').dataset.key` against the key in the publisher portal.

## `[CashbackHive] call init({ key }) first…`

You called an SDK method before initialisation. Wait for `cbh:ready` — see [Lifecycle](https://developer.cashbackhive.com/concepts/lifecycle.md).

## `[CashbackHive] unknown offer "…"`

You passed a slug string to `openOffer()` or `trackingUrl()` but that offer isn't in the SDK's cache. Either fetch it first with `offers.get(slug)` / `offers.list()`, or pass the offer object instead of the slug. See [Click tracking](https://developer.cashbackhive.com/guides/click-tracking.md#passing-a-slug-instead-of-an-offer).

## `[CashbackHive] click tracking is not available for "…"`

The offer's `clickUrl` is `null`. Not every offer supports click tracking; check `offer.clickUrl` and hide or disable the call to action when it's missing.

## `[CashbackHive] member is not signed in`

`member.activity()` requires a signed-in member. Check `auth.isSignedIn()` first, or only render the activity UI once `auth:change` delivers a member.

## Sign-in popup is blocked

`auth.signIn()` must be called synchronously from a user gesture (a click handler). If you `await` something before calling it, browsers treat it as a programmatic popup and block it. The SDK falls back to a full-page redirect in that case, which works but is a worse experience. Restructure so `signIn()` is the first thing the click handler does.

## `signIn()` rejects with "Sign-in window was closed"

The member closed the popup before completing sign-in. This is a cancel, not an error — reset your UI and let them try again.

## Member appears signed out on a returning visit, then signed in a moment later

Expected. On load the SDK finds the stored token and fetches the member in the background; `member.current()` is `null` until that completes, then `auth:change` fires. Drive your UI from `auth:change` rather than a one-off check. See [Members and authentication](https://developer.cashbackhive.com/guides/members-and-auth.md#restoring-a-session-on-load).

## Member is signed out unexpectedly on load

The stored token was rejected by the API (expired or revoked), and the SDK signed the member out automatically. They'll need to sign in again. Nothing to fix on your side.

## `openOffer()` opens nothing / new tab is blocked

Same cause as the sign-in popup: `window.open` outside a user gesture. Call `openOffer()` directly in the click handler, with the offer object already in hand, or pass `{ newTab: false }` to navigate the current tab instead.

## Two copies of the SDK are loaded

Harmless — the second copy sees `window.CashbackHive` already exists and exits — but it means you have two script tags (often one in HTML and one in a tag manager). Remove one.

## TypeScript: `Property 'CashbackHive' does not exist on type 'Window'`

Add the [type declarations](https://developer.cashbackhive.com/reference/types.md#typescript-declarations) to your project and make sure the `.d.ts` file is included by `tsconfig.json`.

## Still stuck?

Collect the following and contact Cashback Hive support through the publisher portal:

* The page URL and `location.origin`
* `window.CashbackHive.version`
* Console output with `data-debug` enabled
* The failing request and response from the Network tab


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.