Troubleshooting
Common problems when running a Hype Stack project, grouped by where they show up. Most come from environment files, skipped migrations, or origin mismatches.
Setup and install
pnpm install fails or packages do not link
Run installs from the repository root. The repo is a single pnpm workspace. Installing inside one app breaks linking.
Use pnpm 12+, not npm or yarn (npm's latest tag still installs pnpm 11: use npm install -g pnpm@12).
error: too many arguments for 'create'
An older CLI that npx cached. It only accepted --name; the current one takes the name as the first argument too.
Refresh with npx -y @hype-stack/cli@latest create my-app, or pass --name my-app.
Cannot find module .../pnpm.cjs, or a shell syntax error from pnpm itself
The project pins pnpm 12, which is a native binary, and an older toolchain cannot reach it. A corepack that predates
pnpm 11 still looks for bin/pnpm.cjs, a file the package no longer ships, so every command dies with
Cannot find module .../pnpm.cjs. An older pnpm trying to switch versions on its own hits a different wall: it skips
the build script that unpacks the real binary and then executes the leftover placeholder, which surfaces as
Syntax error: ")" unexpected or ENOEXEC.
Either way the fix is the same: update the tool instead of letting it switch. Run npm install -g corepack@latest (if
you use corepack) or npm install -g pnpm@12, then re-run pnpm install in the project.
Frontend cannot reach the API
Confirm apps/frontend/.env exists and VITE_API_BASE_URL points at the backend (default http://localhost:3000).
Restart the Vite dev server after changing VITE_* values; they are baked in at startup.
Docker port already in use
Something else owns the Postgres or Valkey host port. Stop it, or change the published port in docker-compose.yml and
update DATABASE_URL / VALKEY_URL to match.
Database
Migrations cannot connect
Containers may still be starting. Run docker compose ps in apps/backend and wait for healthy, then retry
pnpm --filter @hype-stack/backend migration:create. Confirm DATABASE_URL in apps/backend/.env.
Tables missing after compose or template
Pack installs merge Prisma schema and offer to run prisma migrate dev at the end. If you said no, or passed --yes
without a database up, nothing was applied. Run pnpm --filter @hype-stack/backend migration:create. See
Migrations.
Types wrong after a schema change
Re-run the migrate / generate script so the Prisma client regenerates. Kysely reads those types.
Auth
Sign-in fails or callbacks bounce
Almost always an origin mismatch. Check:
FRONTEND_URLon the backendVITE_API_BASE_URLon the frontend- WorkOS redirect URIs or Better Auth
BETTER_AUTH_URL+ Google callback URLs
Every one of these must include the scheme. See
Sign-in 404s with the frontend host inside the backend path
for what a missing https:// looks like.
See Authentication and the starter pack setup pages.
Admin login rejects you
Add your email to SUPER_ADMIN_EMAIL, or have an existing super admin create an admin record. See
Admin app.
Stuck on onboarding
Private routes send users without an organization to /onboarding. Finish org creation or accept an invite. If you
already have an org and still loop, check sdk.users.me and the onboarding route guard.
Billing
Webhooks never update subscription state
For local dev with Stripe, run stripe listen --forward-to localhost:3000/checkout/webhook and put the printed
whsec_... into STRIPE_WEBHOOK_SECRET. Lemon Squeezy and Polar have no local forwarder; use a tunnel and register the
public URL in their dashboards. In production, use the live endpoint secret and confirm events reach
/checkout/webhook.
Checkout works but receipts never arrive
Receipts require RESEND_API_KEY. Without it the pack skips email on purpose.
Mobile
Expo Go will not open the project
The App Store Expo Go is pinned to one SDK. This project needs a matching build from
sign.expo.dev. Pick the SDK in apps/mobile/package.json (currently 57), sign with your Apple
ID, and install that binary. See Mobile.
The app loads, then closes with no error
Metro says the bundle built, the splash screen shows, and a second later the app is gone. No red screen, nothing in the Metro log. That is a native crash, so there is no JavaScript error to find.
It almost always means a native module's JavaScript is on a different Expo SDK than the Expo Go you are running. Check
that every expo-* package in apps/mobile/package.json shares one major:
grep -E '"(expo|expo-|react-native)' apps/mobile/package.jsonIf one is behind, install the version that matches the rest and restart Metro with --clear. To confirm the diagnosis,
plug the phone into a Mac and read the crash report:
Settings > Privacy & Security > Analytics & Improvements > Analytics Data, newest Expo Go-*.ips. A SIGSEGV in
cloneString on the com.facebook.react.runtime.JavaScript thread is this bug.
Phone cannot reach the API
localhost on the device is the phone, not your computer. Set EXPO_PUBLIC_API_BASE_URL in apps/mobile/.env to your
LAN IP (http://192.168.x.x:3000) and restart Metro.
Deploy
Provider CLI not logged in
deploy web checks before creating resources. Run fly auth login or railway login, or set FLY_API_TOKEN /
RAILWAY_API_TOKEN in CI. For deploy mobile it is eas login or EXPO_TOKEN; deploy extension reads store
credentials from the environment and prints the exact keys it is missing.
Custom domain still serves the wrong origin
Set url on the target in stack.json and point DNS first. Update auth provider callbacks and FRONTEND_URL /
VITE_API_BASE_URL to the custom hosts. See Deploy.
Sign-in 404s with the frontend host inside the backend path
Google login dead-ends on a URL that has the frontend domain wedged into the backend's callback path:
https://api.example.com/api/auth/callback/www.example.com/callbackYour frontend host showing up as a path segment of the backend is the tell: an origin variable lost its scheme.
FRONTEND_URL is www.example.com rather than https://www.example.com.
frontendUrl() builds links by concatenation, so a bare host produces the relative string www.example.com/callback.
That reaches Better Auth as the OAuth callbackURL and comes back as a Location header, and a relative Location is
resolved against the URL that issued it - the backend's own callback route:
www.example.com/callback + base https://api.example.com/api/auth/callback/google
= https://api.example.com/api/auth/callback/www.example.com/callbackRailway's RAILWAY_SERVICE_*_URL variables are bare hosts, so copying one into FRONTEND_URL, ADMIN_URL, or
VITE_ADMIN_URL reproduces this exactly.
The same value breaks two more things with no error at all: the CORS allow-list and Better Auth's trustedOrigins
compare against Origin request headers, which always carry a scheme, so a bare host matches nothing and cross-origin
requests simply stop working.
Give every origin variable a full origin - scheme included, no trailing slash - and redeploy: FRONTEND_URL,
ADMIN_URL, SERVER_URL, BETTER_AUTH_URL. The backend prints its resolved value at boot, and CORS should echo the
frontend origin back:
curl -sI -H "Origin: https://www.example.com" https://api.example.com/ping/x | grep -i access-control-allow-originA corrected VITE_* value did not take effect
VITE_* variables are inlined into the bundle at build time, so fixing one in the deploy provider does nothing until
the frontend service rebuilds. A restart redeploys the old bundle with the old value. Backend process.env reads
are per-boot and only need a restart, which is why the same fix can appear to land on one service and not the other.
Migrations failed on release
Read the provider log for the release / pre-deploy command. Fix the SQL or connection string, then redeploy. Use
--skip-migrations only when you intend to migrate out of band.
Related
Every purchase and sponsorship funds my 8+ years of work on open source given freely to the community. It keeps the lights on, funds new packs, and keeps the ecosystem alive. Even a small tier means a lot. Thank you!
