AI Founder OS
Operator runbook

Troubleshooting

Seven problems you will hit and exactly how to fix each one. Read the symptom, check the causes, follow the steps, confirm the proof. No guessing.

Symptom

Deploy is stale. The site does not reflect your latest changes.

Most likely causes

  • The latest deployment on Vercel was triggered from an older commit, not your most recent push.
  • Production is pointed at the wrong branch or a different Vercel project.
  • A custom domain is mapped to a preview deployment instead of production.
  • Vercel build cache is serving an old version of a static page.

Do this now

  1. 1Open Vercel dashboard. Find the latest deployment. Compare its commit SHA to the output of git rev-parse HEAD locally. They must match.
  2. 2Confirm the production branch in Vercel project settings is set to main.
  3. 3Confirm the Vercel project name matches the repo. If you have multiple projects pointing at the same repo, check that the correct one is linked to your domain.
  4. 4Check your domain settings in Vercel. The production domain must point to the Production deployment, not a preview.
  5. 5If the SHAs match but the content is wrong, trigger a manual redeploy from the Vercel dashboard (three-dot menu on the latest deployment). This clears the build cache.

Proof

The deployed site shows the content from your latest commit. The Vercel deployment SHA matches git rev-parse HEAD.

Symptom

Build fails on Vercel but works on your local machine.

Most likely causes

  • Environment variables are missing or different on Vercel. Clerk keys are the most common cause. Without NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY, the prerender step fails.
  • A dependency is imported in code but missing from package.json. Locally it might exist in node_modules from a previous install, but Vercel does a clean install.
  • Node.js version on Vercel differs from your local version. Check the Vercel project settings for the Node version.
  • A feature-flagged module (like Stripe) is imported at the top level. The import runs at build time even when the flag is off. The package must be in dependencies.

Do this now

  1. 1Read the full Vercel build log. The error message tells you exactly what failed.
  2. 2Compare your .env.local file to the Vercel project environment variables. Every variable your code reads must exist in Vercel for the correct environment (Production, Preview, or both).
  3. 3Run npm ls in your local repo and compare to the dependencies in package.json. If a package is in node_modules but not in package.json, add it.
  4. 4Check the Node.js version: node --version locally, then compare to Vercel project settings. Match them.
  5. 5If the error mentions a missing module during prerender, check whether that module is imported at the top of a file. If so, the package must be in dependencies even if the feature is off at runtime.

Proof

npm run build passes locally with the same env vars Vercel has. The Vercel build log shows a successful deployment.

Symptom

Clerk error: Missing publishableKey. Pages fail to prerender.

Most likely causes

  • NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY is not set in Vercel environment variables for the Production environment.
  • CLERK_SECRET_KEY is missing. Server-side auth calls fail during static generation.
  • The variables are set for Preview but not Production, or the other way around.
  • The /_not-found page triggers prerender, which invokes ClerkProvider, which requires the publishable key at build time.

Do this now

  1. 1Go to Vercel project settings, then Environment Variables.
  2. 2Confirm NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY exists and is set for Production.
  3. 3Confirm CLERK_SECRET_KEY exists and is set for Production.
  4. 4If you use Preview deployments, set both variables for Preview as well.
  5. 5After adding or changing variables, trigger a new deployment. Vercel does not retroactively apply env changes to existing deployments.
  6. 6Locally, confirm your .env.local has both keys. Run npm run build to verify prerender works.

Proof

npm run build completes without a Missing publishableKey error. All static pages, including /_not-found, prerender successfully.

Symptom

Stripe or billing route errors even though billing is turned off.

Most likely causes

  • The stripe package is imported at the module level in lib/stripe.ts. The import runs at build time regardless of whether BILLING_ENABLED is set.
  • If stripe is removed from package.json to 'clean up,' the build breaks because the import cannot resolve.
  • The feature flag (billingEnabled) guards runtime execution, not the import statement. This is by design.
  • A route handler imports getStripe() from lib/stripe.ts. The file compiles even when billing is off, so the stripe package must be installed.

Do this now

  1. 1Confirm stripe is listed in dependencies in package.json. Run npm ls stripe to verify.
  2. 2Do not remove stripe from dependencies. The import exists at the module level and the build needs it to resolve.
  3. 3If you see a runtime error when billing is off, check that the error comes from actually calling getStripe(), not from the import. The function throws only when called without STRIPE_SECRET_KEY.
  4. 4If you want to verify billing is off, check that BILLING_ENABLED is not set to '1' in .env.local. The checkout route will return a 404 and the pricing page will show a mailto link.

Proof

npm run build passes. The /api/stripe/checkout route returns 404 when billing is off. No Stripe errors appear in the build log.

Symptom

Mobile changes do not show up on the device or simulator.

Most likely causes

  • The iOS or Android simulator is running a cached version of the JavaScript bundle.
  • Metro bundler is serving a stale bundle. It needs a restart with cache clear.
  • You are running in Expo Go, which cannot load native modules from new dependencies. A dev client rebuild is required.
  • The TestFlight or Play Store build is a compiled binary. JavaScript changes after the build was submitted will not appear until you submit a new build.
  • Hot reload failed silently and the app is still running old code.

Do this now

  1. 1Kill the app on the simulator or device completely. Relaunch it.
  2. 2Stop Metro. Restart with npx expo start --clear or npx react-native start --reset-cache.
  3. 3If you added a native dependency (anything with iOS or Android native code), you must rebuild: npx expo prebuild --clean, then run the native build again.
  4. 4If using Expo Go: switch to a dev client build if the dependency requires native code. Expo Go cannot load custom native modules.
  5. 5If the change is not showing on TestFlight or the Play Store: this is expected. Those are compiled binaries. Submit a new build with eas build or your CI pipeline.
  6. 6Check the Metro terminal output for errors. A red screen or yellow warning often explains why the update did not apply.

Proof

After restarting Metro with cache clear and relaunching the app, the latest changes appear on screen. The Metro terminal shows the updated bundle being served.

SSOT feeding hotspots with a no drive-by edits warningSingle Sourceof TruthHotspotspage.tsxroute.tscomponent.tsxNo drive-by edits outside hotspots

Hotspot discipline prevents scope creep

Symptom

Claude edited files outside the allowed hotspot.

Most likely causes

  • The task script did not include an explicit DO NOT TOUCH list.
  • The task was too broad. Claude interpreted the goal as requiring changes to files you did not intend.
  • Multiple goals were combined into one task. Claude touched extra files to satisfy the second goal.
  • The task did not require a handoff packet, so there was no forced accounting of what changed.

Do this now

  1. 1Run git diff --name-only to see every file Claude changed.
  2. 2Compare that list to the allowed files in your task script. Any file not on the list is a violation.
  3. 3If the unwanted changes are uncommitted: run git checkout -- path/to/file for each file that should not have been touched.
  4. 4If the changes are already committed: run git revert HEAD to undo the entire commit, then rewrite the task with tighter boundaries.
  5. 5Rewrite the task script. Add an explicit HOTSPOT section listing every file Claude may edit. Add a DO NOT TOUCH section listing files that must not change.
  6. 6Add this constraint to every future task: 'If you need to edit a file not listed in the hotspot, stop and report it. Do not edit it.'
  7. 7Require a handoff packet at the end of every task. The packet forces Claude to list every file it changed, which makes violations visible immediately.

Proof

git diff --name-only shows only files listed in the hotspot. The handoff packet lists the same files. No unexpected changes exist.

Symptom

You pushed to main but the live site does not reflect your latest changes.

Most likely causes

  • The Vercel deployment was triggered from an older commit. Your latest push may not have reached the production branch.
  • Environment variables are missing or misconfigured in Vercel project settings. The build may have silently failed or rendered stale content.
  • Your browser is serving a cached version of the page. A hard refresh has not been performed.
  • The production domain is pointing at a preview deployment instead of the production deployment.
  • The Vercel project is linked to a different repository or branch than you expect.

Do this now

  1. 1Open the Vercel dashboard. Find the latest deployment. Compare its commit SHA to the output of git rev-parse HEAD in your local repo. They must match exactly.
  2. 2In Vercel project settings, confirm the production branch is set to main. If it points to a different branch, your pushes to main will not trigger production deployments.
  3. 3Go to Vercel project settings → Environment Variables. Confirm every required variable exists for the Production environment: NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, NEXT_PUBLIC_CLERK_SIGN_IN_URL, NEXT_PUBLIC_CLERK_SIGN_UP_URL, and ADMIN_GRANT_SECRET at minimum.
  4. 4Force-refresh your browser: Cmd+Shift+R (Mac) or Ctrl+Shift+R (Windows). Alternatively, open an incognito window and load the production URL.
  5. 5Confirm you are checking the correct domain. If you have a custom domain, verify in Vercel domain settings that it is mapped to the Production deployment, not a preview.
  6. 6If the commit SHA matches and env vars are correct but content is still stale, trigger a manual redeploy from the Vercel dashboard (three-dot menu → Redeploy). This clears the build cache.

Proof

The Vercel deployment SHA matches git rev-parse HEAD. The production domain serves the latest content. All required environment variables are present in Vercel project settings for the Production environment.

If none of these match your problem, check the build log first. The error message almost always tells you what is wrong. If the build log is clean and the issue persists, check that your local environment matches production exactly: same Node version, same env vars, same dependencies.