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.
My link does nothing
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?