[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-site-config":3,"$fF-1YNHKrSDXbjhAzv-hE6JykPYKI8yiFBn5jjpmLyBc":6,"mdc--cweqxa-key":54},{"gaMeasurementId":4,"bookingUrl":5},"G-7BYTDCVDDR","https:\u002F\u002Ftidycal.com\u002Fcmdcntr\u002F30-minute-meeting",{"post":7,"related":53},{"id":8,"slug":9,"title":10,"description":11,"content":12,"coverImageUrl":13,"coverImageAlt":13,"tags":14,"targetKeywords":20,"demo":21,"featured":25,"tool":15,"status":26,"reviewNote":13,"metaTitle":27,"metaDescription":28,"canonicalUrl":29,"sourceTicketId":13,"agentGenerated":25,"publishedAt":30,"publishedBy":31,"createdAt":30,"updatedAt":32,"authorId":33,"clusterId":34,"ctaId":35,"author":36,"cluster":43,"cta":47},"d88d3b64-47f1-4209-ba4e-f9fd36bdb5e9","fix-bolt-new-app-6-problems","6 Bolt.new Problems That Break Apps in Production (And How We Fix Each One)","Bolt.new ships a working app fast, then the same six issues show up the moment real users arrive. Here is each failure pattern and the exact fix, from a team that does this for a living.","Bolt.new is one of the better AI app builders for getting from idea to running prototype. The problem is not Bolt. The problem is that \"runs in the Bolt preview\" and \"runs in production for paying users\" are different bars, and the gap between them is remarkably consistent across the apps we are asked to rescue. We have fixed enough Bolt.new apps now that the failures rhyme. Here are the six we see most, in roughly the order they bite, with the fix we actually apply for each.\n\n## 1. Environment variables that only exist in the preview\n\nThe most common reason a Bolt app works in the preview and breaks on deploy is environment configuration. Bolt holds your keys in its environment, and the generated code reads them directly. When you export and deploy to Vercel, Netlify, or Railway, those variables do not come with it.\n\n**The fix:** Inventory every key the app reads, set them explicitly in your host's dashboard, and fail loudly when one is missing instead of limping along.\n\n```typescript\n\u002F\u002F Do not let a missing key fail silently three layers deep\nfunction requireEnv(name: string): string {\n  const value = process.env[name]\n  if (!value) throw new Error('Missing required env var: ' + name)\n  return value\n}\n\nconst stripeKey = requireEnv('STRIPE_SECRET_KEY')\n```\n\n## 2. Authentication that protects the screen, not the data\n\nBolt builds a clean login flow. What it usually does not build is server-side enforcement on the endpoints behind that flow. The UI hides the dashboard from logged-out users, but the API that feeds the dashboard will still answer a direct request.\n\n**The fix:** Enforce identity and ownership on every protected endpoint on the server, not in the component. This pattern is identical across AI builders, and we break down the exact failure and fix in [Why AI-Generated Authentication Always Breaks](\u002Fblog\u002Ffix-ai-code\u002Fwhy-ai-generated-authentication-breaks).\n\n## 3. A data model with no constraints\n\nBolt-generated schemas tend to make everything optional and enforce nothing. No foreign keys, no NOT NULL, no checks. It works in the demo because you, the careful creator, only ever entered clean data. Real users do not.\n\n**The fix:** Add the constraints the app actually depends on, then clean up the rows that violate them. Adding a foreign key or a NOT NULL will fail against bad existing data, which is exactly how you find the corruption that is already there.\n\n## 4. Token limits quietly degrading the build\n\nThis one is specific to AI builders and catches people off guard. As your app grows past Bolt's context window, the model can no longer see the whole codebase when it makes a change. It starts editing in the dark, reintroducing bugs you fixed, duplicating logic, and breaking patterns it set up earlier.\n\n**The fix:** Treat the token wall as the signal that the app has outgrown the builder. That is the moment to export to a real repository and work in a normal editor with full-codebase context. If you are at this point, the [vibe-code-to-production migration playbook](\u002Fblog\u002Fvibe-coding\u002Fvibe-code-to-production-migration-playbook) is the next thing to read.\n\n## 5. Deploys that succeed but ship a broken app\n\nBolt apps frequently build fine and then 500 on the first real request. The usual culprits are server-only code that assumed the preview runtime, hardcoded preview URLs, and database connections configured for Bolt's environment rather than your production database.\n\n**The fix:** Do a real deployment dry run against a staging copy of production. Point at the production database, use production URLs, and walk the critical flows before you send a single customer to it. The preview passing tells you almost nothing about the deploy.\n\n## 6. No error handling on the unhappy path\n\nGenerated code handles the case where everything works. It rarely handles the network call that times out, the payment that declines, or the upload that fails halfway. In the demo nothing fails, so the missing handling is invisible. In production it shows up as a frozen screen and a confused customer.\n\n**The fix:** Add error handling and user-visible fallbacks on every external call, especially payments, third-party APIs, and file uploads. Every async boundary needs a plan for failure, not just success.\n\n## Key takeaways\n\n- Set every environment variable explicitly on your host and fail loudly when one is missing.\n- A login screen is not security. Enforce ownership on the server for every protected endpoint.\n- Add real database constraints, then fix the bad data they surface.\n- The token wall is your cue to export Bolt to a real repo and keep building there.\n- Test the deploy against a production-shaped environment, and handle the unhappy path on every external call.\n\nNone of these are reasons to avoid Bolt.new. It is a fast way to get something real in front of people. They are the predictable cost of taking that something to production, and every one of them is fixable. If your Bolt app is past the demo and breaking under real use, this list is usually the whole map.",null,[15,16,17,18,19],"bolt","bolt.new","deployment","debugging","production",[],{"dir":22,"repoUrl":23,"bugBranch":24},"demos\u002Fbolt-production-fixes","https:\u002F\u002Fgithub.com\u002Fcommandcenterio\u002Fcmdcntr-demos","bug\u002Fbolt-production-fixes",false,"published","Fix Bolt.new App: 6 Problems That Break Production","The six Bolt.new failures we see most when an app hits real users, and the exact fix for each: env vars, auth, data model, token limits, deploys, and error handling.","https:\u002F\u002Fcmdcntr.io\u002Fblog\u002Fai-builder-guides\u002Ffix-bolt-new-app-6-problems","2026-07-04T15:08:41.410Z","7452d3cc-b0aa-46e4-96e6-da9c0225c471","2026-07-04T16:23:59.662Z","ed80da88-f3d1-4aa9-9373-18c39fecb740","2540aa0c-e9f9-40ab-ac3a-837f79a1c5a3","c0fcf6a1-58d2-4262-8996-3ad29d58eea5",{"slug":37,"name":38,"avatarUrl":39,"role":40,"bio":41,"isPublic":42},"michael-graham","Michael Graham","\u002Fapi\u002Fpublic\u002Favatar\u002F7452d3cc-b0aa-46e4-96e6-da9c0225c471","Founder & Software Engineer","Obsessed with building top-tier web software and crafting unique, polished user experiences.",true,{"slug":44,"name":45,"color":46},"ai-builder-guides","AI Builder Guides","#F59E0B",{"id":35,"name":48,"ctaType":49,"heading":50,"description":51,"buttonText":52,"url":5,"leadMagnetUrl":13},"Book a Call (blog)","book_call","Shipping AI-generated code that keeps breaking?","Book a free 30-minute call with a senior engineer. We diagnose what is going wrong and give you a concrete fix plan, no obligation.","Book a free call",[],{"data":55,"body":56},{},{"type":57,"children":58},"root",[59,67,74,79,90,372,378,383,400,406,411,420,426,431,448,454,459,468,474,479,488,494,524,529],{"type":60,"tag":61,"props":62,"children":63},"element","p",{},[64],{"type":65,"value":66},"text","Bolt.new is one of the better AI app builders for getting from idea to running prototype. The problem is not Bolt. The problem is that \"runs in the Bolt preview\" and \"runs in production for paying users\" are different bars, and the gap between them is remarkably consistent across the apps we are asked to rescue. We have fixed enough Bolt.new apps now that the failures rhyme. Here are the six we see most, in roughly the order they bite, with the fix we actually apply for each.",{"type":60,"tag":68,"props":69,"children":71},"h2",{"id":70},"_1-environment-variables-that-only-exist-in-the-preview",[72],{"type":65,"value":73},"1. Environment variables that only exist in the preview",{"type":60,"tag":61,"props":75,"children":76},{},[77],{"type":65,"value":78},"The most common reason a Bolt app works in the preview and breaks on deploy is environment configuration. Bolt holds your keys in its environment, and the generated code reads them directly. When you export and deploy to Vercel, Netlify, or Railway, those variables do not come with it.",{"type":60,"tag":61,"props":80,"children":81},{},[82,88],{"type":60,"tag":83,"props":84,"children":85},"strong",{},[86],{"type":65,"value":87},"The fix:",{"type":65,"value":89}," Inventory every key the app reads, set them explicitly in your host's dashboard, and fail loudly when one is missing instead of limping along.",{"type":60,"tag":91,"props":92,"children":97},"pre",{"className":93,"code":94,"language":95,"meta":96,"style":96},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Do not let a missing key fail silently three layers deep\nfunction requireEnv(name: string): string {\n  const value = process.env[name]\n  if (!value) throw new Error('Missing required env var: ' + name)\n  return value\n}\n\nconst stripeKey = requireEnv('STRIPE_SECRET_KEY')\n","typescript","",[98],{"type":60,"tag":99,"props":100,"children":101},"code",{"__ignoreMap":96},[102,114,167,217,296,310,319,328],{"type":60,"tag":103,"props":104,"children":107},"span",{"class":105,"line":106},"line",1,[108],{"type":60,"tag":103,"props":109,"children":111},{"style":110},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[112],{"type":65,"value":113},"\u002F\u002F Do not let a missing key fail silently three layers deep\n",{"type":60,"tag":103,"props":115,"children":117},{"class":105,"line":116},2,[118,124,130,136,142,147,153,158,162],{"type":60,"tag":103,"props":119,"children":121},{"style":120},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[122],{"type":65,"value":123},"function",{"type":60,"tag":103,"props":125,"children":127},{"style":126},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[128],{"type":65,"value":129}," requireEnv",{"type":60,"tag":103,"props":131,"children":133},{"style":132},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[134],{"type":65,"value":135},"(",{"type":60,"tag":103,"props":137,"children":139},{"style":138},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[140],{"type":65,"value":141},"name",{"type":60,"tag":103,"props":143,"children":144},{"style":132},[145],{"type":65,"value":146},":",{"type":60,"tag":103,"props":148,"children":150},{"style":149},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[151],{"type":65,"value":152}," string",{"type":60,"tag":103,"props":154,"children":155},{"style":132},[156],{"type":65,"value":157},"):",{"type":60,"tag":103,"props":159,"children":160},{"style":149},[161],{"type":65,"value":152},{"type":60,"tag":103,"props":163,"children":164},{"style":132},[165],{"type":65,"value":166}," {\n",{"type":60,"tag":103,"props":168,"children":170},{"class":105,"line":169},3,[171,176,182,187,192,197,202,208,212],{"type":60,"tag":103,"props":172,"children":173},{"style":120},[174],{"type":65,"value":175},"  const",{"type":60,"tag":103,"props":177,"children":179},{"style":178},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[180],{"type":65,"value":181}," value",{"type":60,"tag":103,"props":183,"children":184},{"style":132},[185],{"type":65,"value":186}," =",{"type":60,"tag":103,"props":188,"children":189},{"style":178},[190],{"type":65,"value":191}," process",{"type":60,"tag":103,"props":193,"children":194},{"style":132},[195],{"type":65,"value":196},".",{"type":60,"tag":103,"props":198,"children":199},{"style":178},[200],{"type":65,"value":201},"env",{"type":60,"tag":103,"props":203,"children":205},{"style":204},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[206],{"type":65,"value":207},"[",{"type":60,"tag":103,"props":209,"children":210},{"style":178},[211],{"type":65,"value":141},{"type":60,"tag":103,"props":213,"children":214},{"style":204},[215],{"type":65,"value":216},"]\n",{"type":60,"tag":103,"props":218,"children":220},{"class":105,"line":219},4,[221,227,232,237,242,247,252,257,262,266,271,277,281,286,291],{"type":60,"tag":103,"props":222,"children":224},{"style":223},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[225],{"type":65,"value":226},"  if",{"type":60,"tag":103,"props":228,"children":229},{"style":204},[230],{"type":65,"value":231}," (",{"type":60,"tag":103,"props":233,"children":234},{"style":132},[235],{"type":65,"value":236},"!",{"type":60,"tag":103,"props":238,"children":239},{"style":178},[240],{"type":65,"value":241},"value",{"type":60,"tag":103,"props":243,"children":244},{"style":204},[245],{"type":65,"value":246},") ",{"type":60,"tag":103,"props":248,"children":249},{"style":223},[250],{"type":65,"value":251},"throw",{"type":60,"tag":103,"props":253,"children":254},{"style":132},[255],{"type":65,"value":256}," new",{"type":60,"tag":103,"props":258,"children":259},{"style":126},[260],{"type":65,"value":261}," Error",{"type":60,"tag":103,"props":263,"children":264},{"style":204},[265],{"type":65,"value":135},{"type":60,"tag":103,"props":267,"children":268},{"style":132},[269],{"type":65,"value":270},"'",{"type":60,"tag":103,"props":272,"children":274},{"style":273},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[275],{"type":65,"value":276},"Missing required env var: ",{"type":60,"tag":103,"props":278,"children":279},{"style":132},[280],{"type":65,"value":270},{"type":60,"tag":103,"props":282,"children":283},{"style":132},[284],{"type":65,"value":285}," +",{"type":60,"tag":103,"props":287,"children":288},{"style":178},[289],{"type":65,"value":290}," name",{"type":60,"tag":103,"props":292,"children":293},{"style":204},[294],{"type":65,"value":295},")\n",{"type":60,"tag":103,"props":297,"children":299},{"class":105,"line":298},5,[300,305],{"type":60,"tag":103,"props":301,"children":302},{"style":223},[303],{"type":65,"value":304},"  return",{"type":60,"tag":103,"props":306,"children":307},{"style":178},[308],{"type":65,"value":309}," value\n",{"type":60,"tag":103,"props":311,"children":313},{"class":105,"line":312},6,[314],{"type":60,"tag":103,"props":315,"children":316},{"style":132},[317],{"type":65,"value":318},"}\n",{"type":60,"tag":103,"props":320,"children":322},{"class":105,"line":321},7,[323],{"type":60,"tag":103,"props":324,"children":325},{"emptyLinePlaceholder":42},[326],{"type":65,"value":327},"\n",{"type":60,"tag":103,"props":329,"children":331},{"class":105,"line":330},8,[332,337,342,347,351,355,359,364,368],{"type":60,"tag":103,"props":333,"children":334},{"style":120},[335],{"type":65,"value":336},"const",{"type":60,"tag":103,"props":338,"children":339},{"style":178},[340],{"type":65,"value":341}," stripeKey ",{"type":60,"tag":103,"props":343,"children":344},{"style":132},[345],{"type":65,"value":346},"=",{"type":60,"tag":103,"props":348,"children":349},{"style":126},[350],{"type":65,"value":129},{"type":60,"tag":103,"props":352,"children":353},{"style":178},[354],{"type":65,"value":135},{"type":60,"tag":103,"props":356,"children":357},{"style":132},[358],{"type":65,"value":270},{"type":60,"tag":103,"props":360,"children":361},{"style":273},[362],{"type":65,"value":363},"STRIPE_SECRET_KEY",{"type":60,"tag":103,"props":365,"children":366},{"style":132},[367],{"type":65,"value":270},{"type":60,"tag":103,"props":369,"children":370},{"style":178},[371],{"type":65,"value":295},{"type":60,"tag":68,"props":373,"children":375},{"id":374},"_2-authentication-that-protects-the-screen-not-the-data",[376],{"type":65,"value":377},"2. Authentication that protects the screen, not the data",{"type":60,"tag":61,"props":379,"children":380},{},[381],{"type":65,"value":382},"Bolt builds a clean login flow. What it usually does not build is server-side enforcement on the endpoints behind that flow. The UI hides the dashboard from logged-out users, but the API that feeds the dashboard will still answer a direct request.",{"type":60,"tag":61,"props":384,"children":385},{},[386,390,392,399],{"type":60,"tag":83,"props":387,"children":388},{},[389],{"type":65,"value":87},{"type":65,"value":391}," Enforce identity and ownership on every protected endpoint on the server, not in the component. This pattern is identical across AI builders, and we break down the exact failure and fix in ",{"type":60,"tag":393,"props":394,"children":396},"a",{"href":395},"\u002Fblog\u002Ffix-ai-code\u002Fwhy-ai-generated-authentication-breaks",[397],{"type":65,"value":398},"Why AI-Generated Authentication Always Breaks",{"type":65,"value":196},{"type":60,"tag":68,"props":401,"children":403},{"id":402},"_3-a-data-model-with-no-constraints",[404],{"type":65,"value":405},"3. A data model with no constraints",{"type":60,"tag":61,"props":407,"children":408},{},[409],{"type":65,"value":410},"Bolt-generated schemas tend to make everything optional and enforce nothing. No foreign keys, no NOT NULL, no checks. It works in the demo because you, the careful creator, only ever entered clean data. Real users do not.",{"type":60,"tag":61,"props":412,"children":413},{},[414,418],{"type":60,"tag":83,"props":415,"children":416},{},[417],{"type":65,"value":87},{"type":65,"value":419}," Add the constraints the app actually depends on, then clean up the rows that violate them. Adding a foreign key or a NOT NULL will fail against bad existing data, which is exactly how you find the corruption that is already there.",{"type":60,"tag":68,"props":421,"children":423},{"id":422},"_4-token-limits-quietly-degrading-the-build",[424],{"type":65,"value":425},"4. Token limits quietly degrading the build",{"type":60,"tag":61,"props":427,"children":428},{},[429],{"type":65,"value":430},"This one is specific to AI builders and catches people off guard. As your app grows past Bolt's context window, the model can no longer see the whole codebase when it makes a change. It starts editing in the dark, reintroducing bugs you fixed, duplicating logic, and breaking patterns it set up earlier.",{"type":60,"tag":61,"props":432,"children":433},{},[434,438,440,446],{"type":60,"tag":83,"props":435,"children":436},{},[437],{"type":65,"value":87},{"type":65,"value":439}," Treat the token wall as the signal that the app has outgrown the builder. That is the moment to export to a real repository and work in a normal editor with full-codebase context. If you are at this point, the ",{"type":60,"tag":393,"props":441,"children":443},{"href":442},"\u002Fblog\u002Fvibe-coding\u002Fvibe-code-to-production-migration-playbook",[444],{"type":65,"value":445},"vibe-code-to-production migration playbook",{"type":65,"value":447}," is the next thing to read.",{"type":60,"tag":68,"props":449,"children":451},{"id":450},"_5-deploys-that-succeed-but-ship-a-broken-app",[452],{"type":65,"value":453},"5. Deploys that succeed but ship a broken app",{"type":60,"tag":61,"props":455,"children":456},{},[457],{"type":65,"value":458},"Bolt apps frequently build fine and then 500 on the first real request. The usual culprits are server-only code that assumed the preview runtime, hardcoded preview URLs, and database connections configured for Bolt's environment rather than your production database.",{"type":60,"tag":61,"props":460,"children":461},{},[462,466],{"type":60,"tag":83,"props":463,"children":464},{},[465],{"type":65,"value":87},{"type":65,"value":467}," Do a real deployment dry run against a staging copy of production. Point at the production database, use production URLs, and walk the critical flows before you send a single customer to it. The preview passing tells you almost nothing about the deploy.",{"type":60,"tag":68,"props":469,"children":471},{"id":470},"_6-no-error-handling-on-the-unhappy-path",[472],{"type":65,"value":473},"6. No error handling on the unhappy path",{"type":60,"tag":61,"props":475,"children":476},{},[477],{"type":65,"value":478},"Generated code handles the case where everything works. It rarely handles the network call that times out, the payment that declines, or the upload that fails halfway. In the demo nothing fails, so the missing handling is invisible. In production it shows up as a frozen screen and a confused customer.",{"type":60,"tag":61,"props":480,"children":481},{},[482,486],{"type":60,"tag":83,"props":483,"children":484},{},[485],{"type":65,"value":87},{"type":65,"value":487}," Add error handling and user-visible fallbacks on every external call, especially payments, third-party APIs, and file uploads. Every async boundary needs a plan for failure, not just success.",{"type":60,"tag":68,"props":489,"children":491},{"id":490},"key-takeaways",[492],{"type":65,"value":493},"Key takeaways",{"type":60,"tag":495,"props":496,"children":497},"ul",{},[498,504,509,514,519],{"type":60,"tag":499,"props":500,"children":501},"li",{},[502],{"type":65,"value":503},"Set every environment variable explicitly on your host and fail loudly when one is missing.",{"type":60,"tag":499,"props":505,"children":506},{},[507],{"type":65,"value":508},"A login screen is not security. Enforce ownership on the server for every protected endpoint.",{"type":60,"tag":499,"props":510,"children":511},{},[512],{"type":65,"value":513},"Add real database constraints, then fix the bad data they surface.",{"type":60,"tag":499,"props":515,"children":516},{},[517],{"type":65,"value":518},"The token wall is your cue to export Bolt to a real repo and keep building there.",{"type":60,"tag":499,"props":520,"children":521},{},[522],{"type":65,"value":523},"Test the deploy against a production-shaped environment, and handle the unhappy path on every external call.",{"type":60,"tag":61,"props":525,"children":526},{},[527],{"type":65,"value":528},"None of these are reasons to avoid Bolt.new. It is a fast way to get something real in front of people. They are the predictable cost of taking that something to production, and every one of them is fixable. If your Bolt app is past the demo and breaking under real use, this list is usually the whole map.",{"type":60,"tag":530,"props":531,"children":532},"style",{},[533],{"type":65,"value":534},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}"]