Troubleshooting

Common CLI errors and runtime surprises — what each one means and how to fix it.

The most common failures, in two groups: errors the CLI prints, and runtime behavior that surprises people the first time.

CLI errors

Not a superwall project

The CLI couldn't find a project from where you ran it. Run commands from your app root or from inside superwall/ — and check that the project's package.json depends on superwall. See Project structure.

…package.json is named "superwall"

Your project's package.json has "name": "superwall", which shadows the framework import — nothing in the project can import from superwall anymore. Rename the package; superwall create names it after your app for exactly this reason.

No superwall framework found

The project exists but its dependencies aren't installed, or superwall isn't among them. Run bun add superwall (or npm install superwall) inside the project directory.

These N products do not exist on Superwall

A config.ts names a product identifier the dashboard has no product for. The push refuses because every variable on that product would be undefined on device. Either fix the identifier, or create the products — from the dashboard, or with superwall products create from the CLI. See Products and the CLI reference.

Headless paywalls are not enabled for this application

The framework requires the headless paywalls feature on your Superwall application. It's a server-side flag — nothing in the CLI can set it. The account owner needs to have it enabled; contact us if it isn't.

Multiple projects found. Pass --project <id>.

Your account has several Superwall projects, and the command can't guess which one you mean. Add --project <id> (and usually --app <id>) to the command.

Diagnostics block the push

Publishing is immutable, so a paywall with diagnostics — a stray non-page file in app/, a duplicate route — refuses to push. The message names each file and where it belongs. These are the same warnings superwall dev prints, so you'll usually have seen them before push time.

Rename ambiguity in CI

A renamed paywall directory can't be resolved interactively in CI, so the push stops rather than creating a duplicate. Add the --rename old=new flag the error prints. See Push, promote & publish.

paywall x has never been pushed (promote)

Promote only moves the live pointer between pushed versions — there's nothing to point at yet. Push first.

superwall publish requires git

The source snapshot is part of every publish. Install git.

Not signed in

Run superwall login once interactively, or set SUPERWALL_API_KEY (an sk_… key) in CI. superwall dev needs no login.

Runtime surprises

Prices are undefined in dev

Expected. In superwall dev, product variables are undefined until the studio injects your dashboard's products — which is why every read is guarded and the unpriced state is designed, not accidental. The reading rules are in Products.

A number comparison works in dev but not on device

Numeric-looking variables are numbers in dev but strings on a real device ("59.99", "7"). A typeof x === "number" check silently fails on every phone. Coerce with Number() before arithmetic or comparison (Products).

My entry animation already finished when the paywall appears

The SDK preloads paywalls hidden, so components mount long before anyone is looking — a mount-timed animation plays to an empty room. Gate entry animations on presentation, not mount. See Lifecycle & events.

Dark mode looks right on my machine, wrong on device

The mechanism is the dark class the framework maintains on <html> — not prefers-color-scheme. A media query can't see what the device reports and ignores the studio's theme toggle. Style off the class, as shown in Styling & mobile design.

Inside a webview, an <a href> either does nothing or navigates the paywall away from itself. Open links through useActions().openUrl instead. See Actions.

Controls sit in the status bar / under the home indicator

env(safe-area-inset-*) resolves to 0 in previews and some webview contexts, so bare env() math collapses. Always wrap in max() with a floor. See Styling & mobile design.

The payment sheet doesn't open in dev

By design — superwall dev previews the flow and copy but doesn't mount the web checkout payment sheet. Push and open the live URL to verify the checkout itself. See Web checkout.

How is this guide?

On this page