Nov 28, 2025·8 min read

It worked yesterday problem: why AI-generated apps break

Learn why the it worked yesterday problem hits AI-generated apps: expired tokens, changed keys, overwritten fixes, and quick checks to stabilize.

It worked yesterday problem: why AI-generated apps break

What the "it worked yesterday" problem really means

The "it worked yesterday" problem feels unfair because it looks like nothing changed. Same app. Same user. Same button. Then suddenly you get a blank screen, an error message, or a login that spins forever.

Most of the time, "yesterday" doesn't mean the app randomly broke. It means something changed quietly in the background, and your app depended on it without you realizing. With AI-generated apps, those hidden dependencies tend to be bigger because the code is produced fast, settings end up scattered, and the app can lean on temporary defaults that were never meant for real users.

A few invisible changes cause this more often than people expect:

  • A session or permission expired, so the app no longer has access to what it needs.
  • A key, password, or environment setting was rotated, renamed, or removed.
  • A provider changed a limit, security rule, or setting and your app now fails a check.
  • The code was regenerated or re-copied, and a working fix got overwritten.

That’s why it shows up so often in prototypes and early launches. A prototype is usually built to prove a flow, not to survive real-life conditions like timeouts, new users, rate limits, or an accidental redeploy. AI tools can generate a working demo quickly, but they often skip the guardrails that make failures predictable and easy to diagnose.

A simple example: you demo a signup flow on Monday using your own browser. On Tuesday, a new user tries it and gets blocked. Nothing in the UI changed, but the app was relying on a temporary token stored in your browser, or a backend setting that only worked for your account.

The good news is that these failures are usually practical, not mysterious. If you treat "it worked yesterday" as a clue that something changed off-screen, it becomes an investigation with a clear end, not a guessing game.

Why AI-generated apps run into this more often

The "it worked yesterday" pattern can happen in any software, but it’s extra common in AI-generated apps because the goal is usually a fast demo, not long-term stability. The app looks finished on the surface, while the reliability work underneath is missing.

Why speed creates fragility

AI tools are great at producing something that runs once: a login screen, a database table, an API call, a dashboard. Production apps need guardrails around those parts. Without them, normal changes can break core flows.

Common patterns include loose config and secret handling, auth that only works on the happy path, missing tests, too many integrations added too quickly, and a messy structure where one change unexpectedly affects multiple screens.

Small changes ripple more

In a clean codebase, a key change usually breaks one place and the error points you to it. In a rushed, generated codebase, the same value might be duplicated across files, or a helper function might exist in slightly different versions. Debugging starts to feel random.

Example: a founder updates an API key to switch from a test account to a live account. The app still builds, but one endpoint uses the old key from a forgotten config file. Auth fails and users get stuck in a login loop.

This is the kind of situation FixMyMess is built for: taking AI-generated prototypes and adding basic guardrails (clear environments, safer secret handling, and a more maintainable structure) so yesterday’s demo doesn’t become today’s outage.

Expired sessions and tokens (auth that times out)

A lot of "it worked yesterday" failures are just login passes expiring.

In plain language, a session or token is a temporary pass that proves you already logged in. Apps use it so you don’t have to type your password on every click. The catch is that these passes are designed to expire, sometimes after minutes or hours.

AI-generated prototypes often miss the unglamorous parts of auth: renewing the pass, handling timeouts, and keeping users from getting stuck. So everything looks fine right after sign-in, then breaks later.

Typical triggers include tokens expiring with no refresh flow, refresh being implemented but not wired into the UI, server and client clocks disagreeing, or tokens being stored in the wrong place (so the app "forgets" you on refresh).

Symptoms you can spot without reading code: users get randomly logged out, the same action works right after login but fails later, or the app starts showing "Unauthorized" errors. In logs, you may see 401 or 403, which usually means "you are not allowed" or "your pass is no longer valid."

Quick questions that narrow it down:

  • Does it fail only after some time?
  • Does refreshing the page make it worse?
  • Does logging out and back in temporarily fix it?

Example: a demo user signs in, tests checkout, and it works. Two hours later, real users hit "Save" and get kicked back to the login screen. That pattern strongly suggests token expiration.

Teams like FixMyMess typically fix this by making token refresh reliable, handling timeouts gracefully, and verifying the behavior with real-world wait times, not just a quick happy-path test.

Changed API keys, environment variables, and provider settings

Another common cause isn’t a bug in your code. It’s a broken connection to something your app depends on, like email, payments, maps, storage, or login.

Apps talk to those services using secrets: API keys, client IDs, webhooks, and callback URLs. Those values can live in environment variables on your host, a provider dashboard (Stripe, SendGrid, Google, etc.), a config file in the repo, or a secret manager. When any one of them changes, everything can look fine locally but fail in production.

What can change overnight? Providers rotate keys, revoke keys after suspicious activity, or disable a key that was exposed in a public repo. Trials end. Usage limits get hit. Someone edits settings in a dashboard and forgets they did it. Even small switches like changing a redirect URL or toggling a mode can block real users.

The symptoms are confusing because the app still loads, but specific features stop working: payments fail, maps don’t render, emails don’t send, uploads return 403 errors, or login loops back to the sign-in page.

Quick checks that usually save time:

  • Confirm you’re in the right environment (prod vs dev) and the right keys are set there.
  • Look for recent provider changes: revoked keys, expired trials, exceeded quotas.
  • Check deployment logs for missing variables, permission errors, or "invalid API key" messages.
  • Verify webhook URLs and redirect/callback URLs match your current domain.
  • Make sure nobody hard-coded a key in a file that gets overwritten during deploy.

If you inherited an AI-generated app, it’s common to find placeholders, duplicated keys across environments, or secrets hard-coded in the wrong place. FixMyMess often starts with a fast audit to locate every secret and confirm which provider setting is breaking production.

Dependencies and platform updates that break the build

Close security gaps now
Fix exposed secrets and common security holes before real users find them.

Sometimes nothing in your repo changed, and the app still breaks. That’s because the code isn’t the only moving part. Your app depends on packages, runtimes, hosting settings, and third-party services that can change without you noticing.

AI-generated projects are especially vulnerable because they often pin versions poorly (or not at all). You might see a package.json without a lockfile, vague ranges like ^1.2.0, or instructions that pull "latest" every time. The next install or deploy fetches a slightly newer dependency that behaves differently, and now a previously working feature fails.

Platforms change too. A host may bump the default Node version, a managed database may upgrade its engine, a serverless provider may tighten request limits, or a browser update may expose a CSS or JavaScript edge case. It doesn’t feel like "a change you made," but it’s still a change your app has to survive.

Signals that point to dependencies or platform updates:

  • New build warnings or errors that weren’t there before
  • Deploys suddenly failing on the hosting provider
  • A feature works locally but fails in production after a fresh install
  • The UI looks slightly off without any design edits
  • Errors mention a package name, Node/Python version, or a database driver

Scenario: your demo worked on Friday. On Monday, a fresh deploy pulls a new version of a date library and a checkout form starts rejecting valid dates. No one touched the code, but the behavior changed.

To reduce repeat breakage, focus on repeatable builds: commit lockfiles, avoid vague version ranges, pin runtime versions (Node, Python) in project settings, and read deploy logs before trusting what the UI shows.

If you inherited an AI-built codebase with unstable builds, FixMyMess can audit it and identify which dependency or platform change is actually causing the break before you burn hours guessing.

Regenerated code overwriting your previous fixes

One sneaky cause is code regeneration. Many AI-built apps aren’t treated like normal codebases. They’re treated like output that can be re-made at any time. That’s convenient until it quietly wipes out the changes that made the app work.

Regeneration can happen when someone re-prompts the tool, clicks an auto-fix button, re-syncs a project, or asks for a clean rebuild after a small error. Some tools also rewrite files when you change a high-level setting or add a feature.

Fixes disappear because the change was made in a place the generator "owns." For example, you patch a bug directly in a component file, then the next run replaces that file from a template. Without a clear "this file is safe to edit" rule, you don’t really own the code you touched.

Symptoms tend to look like:

  • The exact same bug returns after a small change
  • A file you edited looks newer, but your lines are gone
  • Things fail in a way that feels like time travel: "Why is it back?"
  • Git history (if you have it) shows big rewrites instead of small edits

Example: you fix a login redirect by changing two lines. The next day you ask the AI to add a settings page. It regenerates the routing file and your redirect fix vanishes.

To prevent this, protect fixes: mark key files as human-owned, keep notes on what changed and why, keep critical logic in one place when possible, and use version control so you can compare and restore.

Teams like FixMyMess often see this pattern in projects built with Lovable, Bolt, v0, Cursor, or Replit. A good first step is identifying which files are being overwritten and moving critical logic out of the blast zone.

Step-by-step: how to narrow down what changed

When you hit "it worked yesterday," don’t guess. Find the smallest change that explains the break.

Start with a short timeline since the last time it worked. Include anything that feels minor: a deploy, a tweak in an auth provider dashboard, someone cleaning up env vars, or an AI tool regenerating part of the app.

Next, confirm where you’re testing. Many AI-made apps behave differently in dev, staging, and production because they use different keys, different databases, or different callback URLs. Don’t compare "local worked" with "production broken" without checking.

A simple flow:

  • Lock your test: same account, same device/browser, same steps each time.
  • Capture the first error you see. Note the time and where it appears (screen message, server logs, browser console).
  • Pick one suspect area: auth/session, API keys and env vars, database, or a recent deploy/build change.
  • Try one controlled change: undo or roll back a single recent change (or test the previous deploy) and retest.
  • Write down what happened after each test so you don’t circle back to old guesses.

Example: users suddenly can’t log in. If it started right after a deploy, suspect auth callback URLs or environment variables. If it started after "waiting overnight," suspect expired tokens or session settings. If it started right after regenerating code, suspect an overwritten fix.

If you inherited an AI-generated prototype and the break feels random, FixMyMess often starts with a quick diagnosis that puts the failure into one of these buckets, then verifies the fix with repeatable tests.

Common traps that waste hours

Track down config and keys
We’ll locate missing env vars, bad keys, and mismatched settings across dev and production.

The fastest way to lose a day is to chase what you can see (a broken button, a blank page) instead of what changed behind the scenes. AI-generated apps often fail where the UI can’t explain it: sessions expire, a config value is missing, or the app is talking to the wrong service.

A common trap is debugging the wrong environment. You fix things locally and everything looks fine, but production is still broken because the deployed app has different environment variables, different secrets, or a different database. If the issue only happens for real users, assume production is where the bug lives until proven otherwise.

Another time sink is sharing only screenshots. A screenshot hides the exact error text, the timestamp, and the request that triggered it. Copy the error message, note when it happened, and save the full log line if you have it. One line often points straight to an expired token, a missing API key, or a permission change.

Mistakes that cause the most thrash:

  • Fixing the visible page while the real cause is auth, permissions, or config
  • Editing dev settings when the break is only in staging or production
  • Pasting partial errors (or screenshots) instead of the full message and time
  • Changing several settings at once, then not knowing which one mattered
  • Hitting regenerate to reset, then overwriting yesterday’s working fix

Example: you update a prompt to clean up the login flow, regenerate the code, and the app compiles again. But regeneration replaced your working session refresh logic, so users start getting logged out after a few minutes.

If this pattern keeps happening, a simple change log and a quick audit of auth, secrets, and deployments can save you. Teams bring these cases to FixMyMess when they need someone to trace the real change and make sure the fix survives the next regeneration.

Quick checklist before you panic

The goal isn’t to guess the cause. It’s to learn whether the break is tied to a user, a browser session, a deploy, or a third-party service.

Do these quick tests first:

  • Try the same action in a private/incognito window. If it works there, you’re likely dealing with an expired session, a stuck cookie, or cached front-end code.
  • Ask whether any API key, password, or secret changed in the last 24-72 hours (payments, email, OAuth apps, database passwords).
  • Think back: did you redeploy, change hosting settings, or update a package? Small config changes can break production.
  • Check logs around the exact time it broke. Look for first-error timestamps and messages like "invalid token," "unauthorized," "missing env," or "cannot connect."
  • Confirm who is affected. Everyone, or only certain accounts/roles/new signups? That points to permissions, role checks, or data differences.

Example: the founder can still log in, but new users can’t. That often means the signup flow is failing (email provider key changed, rate limits hit, or a role assignment bug), not the whole app.

If you can answer these five checks in 10 minutes, you usually cut hours of guesswork. If you inherited AI-generated code and the signals are messy, FixMyMess can run a free code audit and tell you what changed and what to fix first.

A simple scenario: the demo worked, then users got locked out

Stop token and session failures
If login loops or random logouts started overnight, we can trace and fix the auth flow.

A founder demos a new AI-built app to an investor on Tuesday. Login works, the dashboard loads, and the payment test goes through. On Wednesday morning, real users start signing up and every login attempt fails. The founder didn’t change any code, so it feels random.

One likely cause is token and session handling. Many prototypes use short-lived tokens or a development-only auth setup that looks fine in a quick demo. Overnight, token lifetime ends, the refresh flow is missing, or the app can’t renew the session. Users get bounced back to the login screen or see a generic "unauthorized" error.

So the founder checks: does it fail only after some time, or immediately for new logins? They try logging in on a fresh browser, then look for "token expired" or "invalid session" in logs. If they see it, the fix is usually a proper refresh flow, predictable server behavior, and safe token storage.

Another common cause is a rotated API key. A payment, email, or auth provider key can be changed, disabled, or replaced. The app keeps using the old key stored in an environment variable, so requests start failing.

A fast way to narrow it down:

  • Re-test login in an incognito window to rule out cached sessions.
  • Check logs for "expired token" vs "invalid API key".
  • Verify current key values in the deployment environment.
  • Confirm provider settings (allowed domains, callback URLs, rate limits).
  • After a fix, run the same flow twice: now and again tomorrow.

To prevent the same surprise next week, lock down where secrets live (no hardcoding), add basic monitoring for auth and key failures, and avoid regenerating code on top of production fixes. If the codebase is AI-generated and hard to untangle, a focused audit from FixMyMess can pinpoint whether it’s token handling, secrets, or a regeneration overwrite.

Next steps to make it stop happening

To reduce the "it worked yesterday" pattern, treat your AI-made app like a real product, not a one-time demo. Most "mystery breakages" are small changes with no record, no checks, and no alarms.

Stabilize what changes most

Start by freezing the moving parts. If your app depends on libraries, hosting defaults, or provider settings, small updates can quietly change behavior.

  • Pin dependency versions so installs are repeatable.
  • Lock down environment variables and secrets (who can change them, and where they live).
  • Add basic monitoring: an uptime check plus alerts for login errors and failed API calls.
  • Keep releases boring: one deploy method, one place to view logs.
  • Make regeneration opt-in: don’t let a tool rewrite files without review.

If a setting can break payments, login, or core data, it shouldn’t be editable on a whim.

Make changes visible and test the risky paths

Keep a lightweight change log: prompt changes, key rotations, deploy times, and provider updates. When something breaks, you can compare "last working" to "first broken" in minutes.

Add a few guardrail tests for flows that tend to fail: login, signup, password reset, and anything that depends on an API key. Even simple checks before deploy can catch missing env vars, broken redirects, and obvious auth failures.

If breakages keep coming back, or you’re seeing security issues like exposed secrets and SQL injection risk, it helps to bring in someone who can untangle and harden the codebase. FixMyMess (fixmymess.ai) offers a free code audit to pinpoint the real causes, then repairs and prepares AI-generated apps for production with expert verification so fixes don’t disappear after the next deploy.

FAQ

What does “it worked yesterday” usually mean in a web app?

It usually means something changed outside the code you were looking at: a session expired, a secret changed, a provider tightened a rule, a dependency updated, or a redeploy pulled in different settings. The app didn’t “randomly” break; it lost a hidden assumption it was relying on.

What’s the fastest first check when something breaks overnight?

Retest the exact same steps with the same account, then try once in a private/incognito window. If incognito works, suspect a stuck session, cookies, or cached frontend assets rather than a brand-new logic bug.

How do I tell if it’s an expired token or session problem?

Login loops, random logouts, and actions that fail after being idle are classic signs. If you see “Unauthorized” errors or 401/403 in logs, it’s often an expired token, a missing refresh flow, or a permission mismatch between users.

What are the signs an API key or environment variable changed?

A broken connection usually shows up as one feature failing while the rest of the app loads, like payments failing, emails not sending, uploads getting denied, or OAuth redirecting back to sign-in. Provider dashboards, rotated keys, expired trials, quotas, or a missing environment variable are common causes.

Why do AI-generated apps hit this problem more often?

AI-generated code often duplicates config, uses defaults that aren’t safe for production, and skips the “boring” reliability parts like retries, timeouts, and error handling. That makes small background changes feel huge, because the app has no guardrails when something is slightly different than the demo.

Can the app break even if nobody changed the code?

If builds suddenly fail or behavior changes after a fresh install or redeploy, suspect dependency drift or a runtime/platform change. Missing lockfiles, loose version ranges, or an updated Node/Python version can change behavior without any edits to your repo.

How can regenerated AI code undo my previous fixes?

Yes, regeneration can overwrite fixes if you edited files the generator “owns.” A strong clue is the exact same bug returning after you used an AI tool to add a feature or “auto-fix” something, even though you remember patching it before.

What information should I collect before asking someone for help?

Capture the first visible error text, the timestamp, and where it happened (browser console vs server logs). Also note whether it affects everyone or only new users, specific roles, or certain browsers, because that quickly points to auth, permissions, or environment differences.

How do I prevent “it worked yesterday” outages from repeating?

Lock down secrets to one place, stop hard-coding keys, and keep dev/staging/prod clearly separated. Pin dependency versions, commit lockfiles, and keep changes small and recorded so you can connect “first broken” to “last working” quickly.

When should I bring FixMyMess in to fix an AI-generated app?

If you’re stuck in guessing loops, seeing login/auth failures, exposed secrets, or the app keeps breaking after redeploys or regeneration, bring in help. FixMyMess can run a free code audit, identify the real cause, and repair the codebase with human verification so it holds up in production, often within 48–72 hours.