Common Issues

Works in preview but breaks in production

Why it happens

An app that runs flawlessly in preview can break the moment you publish. This is almost always caused by environmental differences between the two runtimes - preview and production each have their own isolated environment, filesystem, and configuration.

Info

Preview and production are completely separate containers. A change in one does not automatically propagate to the other. See Preview vs Published for details.


Common culprits

Environment variables not set in production

The most frequent cause. If your code reads

process.env.STRIPE_SECRET_KEY
and that variable exists in preview but not production, the app will fail.

What to check:

  • Open the Manage → Secrets panel in your workspace
  • Confirm every variable your app needs is present in production
  • Environment variables flow automatically on publish, but new keys( not values) must be added to
    .env
    by the agent and then republished, the Secrets UI(Manage → Secrets) can only edit values of existing keys, not add new ones
  • Re-publish after adding missing variables

Tip

Agents often set variables in preview during development via

.env
files. If a key was set in the preview pod but never written to
.env
, it will not be present in production. Ask the agent to add any missing keys to
.env
, then re-publish.


Hardcoded
localhost
or preview URLs

Code that references

http://localhost:3000
or your preview URL (
{slug}.preview.emergentagent.com
) will break in production because those addresses are unreachable from the live published app.

Examples:

  • API base URLs:
    const API = "http://localhost:8000"
  • Webhook callbacks:
    callbackUrl: "https://my-app.preview.emergentagent.com/hook"
  • OAuth redirect URIs hardcoded to preview

Fix:

Use environment variables for all URLs:

JavaScript
const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000";

Set

NEXT_PUBLIC_API_URL
differently in preview vs production.


CORS configuration pointing to the wrong origin

If your backend explicitly allows only your preview domain:

Python
allowed_origins = ["https://my-app.preview.emergentagent.com"]

…production requests from

https://my-app.emergent.host
(or your custom domain) will be blocked.

Fix:

  • Use an environment variable for allowed origins
  • Or allow both domains
  • Or use a wildcard pattern if security allows

Files written at runtime disappear

Production containers use an ephemeral filesystem. Any file your app writes to disk (uploads, generated PDFs, cached images) will be lost on restart or scale-out.

Symptoms:

  • User uploads work initially, then vanish
  • Generated files return 404 after a few hours
  • SQLite databases lose data

Fix:

Use Emergent Object Store for persistent file storage. Never rely on the local filesystem for data that must survive restarts.

Do not use local disk for persistence

The container filesystem is wiped on every re-publish and can be cleared at any time during autoscaling.


Missing system dependencies

Preview may have been running on a container that happened to have a system tool installed, but production does not.

Common examples:

ToolUsed forSymptom in production
ffmpeg
Video encoding, audio extraction"ffmpeg: command not found"
PlaywrightBrowser automation, screenshotsChromium binary missing
ImageMagickImage resizing, format conversion"convert: not found"
wkhtmltopdfHTML-to-PDF renderingPDF generation fails silently

Fix:

Declare dependencies in your project:

  • Add
    playwright install
    to your build script
  • Declare the required package dependencies explicitly in your project configuration
  • Or ask the agent to install it via system packages

If the tool was present in preview by chance, you must explicitly require it for production.


Webhooks still pointing to preview

External services (Stripe, Twilio, GitHub) may still have webhook URLs pointing to your preview instance.

What happens:

  • Payment confirmations arrive in preview but not production
  • SMS replies are processed in the wrong environment
  • OAuth flows redirect to the old URL

Fix:

  • Log into each third-party service
  • Update webhook/callback URLs to your production domain
  • Test the flow end-to-end in production

Use environment-specific webhook secrets

Store separate webhook signing secrets for preview and production so you can safely test webhooks without triggering real side effects.


Debugging checklist

1

Compare environment variables

Open the Preview → Manage → Secrets panel and ensure every variable in preview also exists in production with the correct value. Remember: new keys must be added to

.env
by the agent and republished.

2

Check logs

View production logs in the workspace. Look for missing-variable errors, connection timeouts, or "command not found."

3

Search for hardcoded URLs

Grep your codebase for

localhost
,
127.0.0.1
,
.preview.emergentagent.com
and replace with environment variables.

4

Verify CORS origins

Ensure your backend allows requests from your production domain (or custom domain if configured).

5

Audit file writes

If your app writes files, confirm they go to Object Store, not

/tmp
or the project directory.

6

Confirm system dependencies

If preview worked but production crashes on a missing binary, declare that dependency explicitly in your project configuration.

7

Update external webhooks

Check every third-party integration and point webhooks to your live domain.


Still broken?

If none of the above applies, describe the exact error message in chat - agents can compare your preview and production configurations and identify the mismatch.

Was this page helpful?

Related pages