Hvorfor appen din fungerer lokalt, men feiler i produksjon
Ekte årsaker og konkrete løsninger. AI optimaliserer for en fungerende demo, ikke et produksjonssystem. Med 15–30 stille arkitekturbeslutninger per funksjon, der hver har rundt 70% nøyaktighet, er sannsynligheten for at ALLE er korrekte praktisk talt null.
«Det fungerer på maskinen min» er den eldste vitsen innen programvareutvikling. Med AI-genererte apper er det ingen vits — det er standardtilstanden. AI tenker ikke på produksjon. Den vet ikke hva en lastbalanserer, tilkoblingspool eller secrets manager er. Den ser bare én ting: din lokale kontekst, din fil, koden som kjører på maskinen din akkurat nå.
Når AI bygger en funksjon, tar den 15–30 stille arkitekturbeslutninger: hvilken database, hvordan koble til et API, hvor lagre nøkler, hvordan håndtere feil. Hver beslutning har omtrent 70% sjanse for å være korrekt. Men for at hele funksjonen skal fungere i produksjon, må alle beslutninger være korrekte. Sannsynligheten? Med 20 beslutninger: 0.7^20 = 0.08%. Praktisk talt null.
Denne artikkelen dekker de seks vanligste grunnene til at AI-apper fungerer lokalt og krasjer i produksjon — med konkrete eksempler og løsninger. Hvis du bygger med Cursor, Bolt, Lovable, Replit eller et annet AI-verktøy, er denne guiden for deg.
Miljø og konfigurasjon
Dette er den mest åpenbare og samtidig vanligste årsaken til produksjonsfeil: konfigurasjon som bare fungerer lokalt. .env-filen din på laptopen har ekte API-nøkler, korrekte URL-er, fungerende hemmeligheter. I produksjon? Plassholdere, manglende variabler eller helt andre adresser.
AI tenker aldri på konfigurasjonshåndtering — den ser bare lokal kontekst. Når den genererer kode som kobler til et API, skriver den http://localhost:3000 direkte i koden. Når den trenger en API-nøkkel, oppretter den en variabel med en standardverdi. Når den bygger en database-URL, hardkoder den tilkoblingsstrengen.
Typiske problemer:
- Hardkodede URL-er —
http://localhost:3000/apii stedet for en miljøvariabel. Fungerer lokalt, peker ingensteds i produksjon. - Manglende miljøvariabler — i produksjon har du ingen
.env-fil. Du må sette variabler i hostingpanelet ditt (Vercel, Railway, Render). - HTTP vs HTTPS — lokalt bruker du
http://, produksjon kreverhttps://. Å blande protokoller forårsaker nettleserblokkering (mixed content) og CORS-feil. - Ulike API-nøkler — Stripes testnøkkel vs produksjon. Firebase dev-nøkkel vs prod. AI vet ikke at forskjellen finnes.
Slik fikser du det
Eksternaliser ALL konfigurasjon. Hver URL, hver nøkkel, hver hemmelighet bør komme fra en miljøvariabel — aldri fra kildekode. Bruk en hemmelighetsbehandler (f.eks. Doppler, AWS Secrets Manager, Vercel Environment Variables). Opprett en .env.example-fil med navnet på hver påkrevd variabel (uten verdier) og legg den til i repoet som dokumentasjon.
Databaseantakelser
AI elsker SQLite. Den er enkel, krever ingen server, det er bare en fil. Perfekt for en prototype. Problemet? Serverløse plattformer (Vercel, Netlify Functions, AWS Lambda) støtter ikke SQLite fordi hver forespørsel kan treffe en annen instans — det finnes ikke noe delt filsystem.
Men databasen er ikke bare motoren. Det er et helt sett med antakelser AI gjør stille:
- Manglende indekser — en spørring fungerer lynraskt på 50 rader. På 50 000? Tar 30 sekunder. AI legger ikke til indekser fordi på små data ser man ingen forskjell.
- Ingen tilkoblingspooling — hver HTTP-forespørsel åpner en ny databasetilkobling. Med 100 samtidige brukere har du 100 åpne tilkoblinger. Databaser har grenser — vanligvis 20–100 tilkoblinger. Overskrider du det: krasj.
- Skjema som ser bra ut i en demo — ingen relasjoner, ingen begrensninger, ingen typer. Data er inkonsistent, men det syns ikke på 50 rader.
- Ingen migreringer — AI oppretter tabeller «i farten». I produksjon kan du ikke droppe databasen og gjenskape den — du har ekte brukerdata.
Slik fikser du det
Bruk PostgreSQL eller MySQL i produksjon. Konfigurer tilkoblingspooling (PgBouncer, Supabase har det innebygd). Legg til indekser på kolonner brukt i WHERE og JOIN. Planlegg en migrasjonsstrategi — bruk et verktøy som Prisma Migrate, Drizzle eller vanlige SQL-filer med versjonering. Modifiser aldri produksjonsskjemaet manuelt.
Sikkerhet som ikke eksisterer
Veracodes rapport «2025 GenAI Code Security Report» fant at LLM-er innførte en OWASP Top 10-sårbarhet i 45% av testtilfellene. Georgetown-instituttet CSET fikk et lignende resultat: nesten halvparten av kodebitene evalueringen deres produserte, inneholdt utnyttbare feil. Dette er ikke et marginalt problem. Og kode som «fungerer» på localhost trenger ikke være sikker.
En skanning av 5 600 vibe-kodede apper, utført av Escape.tech, avslørte over 2 000 alvorlige sårbarheter og over 400 eksponerte hemmeligheter. Agentplattformen Moltbook eksponerte 1,5 millioner API-tokens gjennom en feilkonfigurert Supabase-database uten effektiv Row Level Security. Og en skanning av Lovable-bygde apper fant 170 prosjekter — omtrent én av ti analyserte — som eksponerte databasene sine gjennom manglende RLS (CVE-2025-48757): hvem som helst uautentisiert kunne lese og skrive vilkårlige tabeller.
Problemer jeg ser regelmessig:
- API-nøkler hardkodet i frontend-JavaScript — hvem som helst kan åpne DevTools og kopiere dem. Jeg har sett dette flere ganger i klientapplikasjoner.
- Ingen inputvalidering — SQL-injection, XSS, path traversal — AI legger sjelden til validering fordi på localhost prøver ingen å bryte seg inn i applikasjonen din.
- Ingen Row Level Security — Supabase uten RLS betyr at hver bruker kan lese og modifisere alle andre brukeres data.
- Ingen rate limiting — uten begrensninger kan noen kalle API-et ditt en million ganger per minutt. Resultat: en skyhøy API-regning, et DDoS-angrep, eller begge deler.
Slik fikser du det
Kjør en OWASP Top 10-gjennomgang. Aktiver Row Level Security på Supabase. Valider alle inputs på serversiden (stol aldri på klienten). Skann repoet ditt etter eksponerte hemmeligheter (bruk gitleaks eller trufflehog). Legg til rate limiting på alle offentlige endepunkter. Flytt API-nøkler fra frontend til backend.
Stille feil og ressurslekkasjer
Applikasjonen din fungerer for de første 100 forespørslene. Forespørsel nummer 1 001 forårsaker en krasj — alle databasetilkoblinger er uttømt. Hvorfor? Fordi AI aldri lukket dem. Hver forespørsel åpnet en ny tilkobling, men ingen frigav den.
Det samme gjelder filhåndtak, WebSocket-lyttere, timere og abonnementer. AI oppretter ressurser, men frigir dem ikke. På localhost legger du ikke merke til det fordi serveren startes på nytt hvert par minutt og tilbakestiller alt. I produksjon kjører serveren kontinuerlig — og ressursene tar slutt.
Enda verre er stille feil:
- Tomme
try/catch-blokker — betaling feiler, webhook avfyres ikke, men brukeren ser ingen feil. Data forsvinner stille. - Race conditions — flere samtidige API-kall løses i tilfeldig rekkefølge. Ingen idempotens betyr duplikater eller inkonsistente data.
- Hot reload maskerer feil — i dev-modus viser React advarsler. I produksjonsbygget forsvinner de. En komponent kaster — hele appen blir hvit fordi det ikke finnes noen error boundaries.
- Ingen global feilbehandler — et uhåndtert unntak dreper Node.js-prosessen. På localhost er omstart umiddelbar. I produksjon — nedetid.
Slik fikser du det
Legg til error boundaries på frontend (React: ErrorBoundary). Legg til en global feilbehandler på backend (process.on('uncaughtException')). Ta i bruk strukturert logging (Sentry, LogRocket, Pino). Lukk databasetilkoblinger etter bruk (eller bruk tilkoblingspooling). Rydd opp lyttere og timere i useEffect cleanup. Belastningstest — å sjekke at det fungerer én gang er ikke nok.
Skadene i virkeligheten
Dette er ikke teoretiske trusler. Dette er hendelser som allerede har skjedd:
- Amazon — fire Sev-1-hendelser i detaljhandelen på én uke, inkludert et seks timers kassaavbrudd som interne dokumenter knyttet til rundt 6,3 millioner tapte bestillinger. Dekningen koblet trenden til GenAI-assisterte endringer; Amazon bestrider at AI-skrevet kode var involvert. Uansett: selv Amazon krever nå ekstra gjennomgang av AI-assisterte produksjonsendringer.
- Ukontrollerte skyregninger — AI-prototypede tjenester distribuert uten kostnadskontroll overrasker regelmessig eierne sine. AI vet ikke at
t3.microkoster noe helt annet ennr5.4xlarge. Kostnadsskalering er noe AI aldri tenker på. - Stripe-integrasjoner — webhook-handlere bygget mot utdaterte API-former har levert doble belastninger i uker før noen la merke til det.
- Final Round AIs undersøkelse blant 18 CTO-er — 16 rapporterte produksjonskatastrofer direkte forårsaket av AI-generert kode.
- CodeRabbits analyse av 470 open source-PR-er — AI-medforfattet kode hadde ~1,7x flere problemer totalt, rundt 2,7x flere XSS-klassede funn og ~8x flere ytelsesproblemer av typen overdrevne I/O-operasjoner enn menneskeskrevet kode.
Mønsteret gjentar seg: AI genererer kode som ser bra ut. Den består kodegjennomgang (fordi den er lesbar). Den består tester (fordi den bare tester at alt går bra). Så eksploderer den i produksjon fordi ingen sjekket ytelse under belastning, feilhåndtering, sikkerhet eller infrastrukturkostnader.
Hvordan du faktisk fikser det (produksjonsklar sjekkliste)
Før du ruller ut applikasjonen din, gå gjennom disse punktene. Hvert uoppfylt punkt er en potensiell produksjonsfeil. Denne sjekklisten ble bygd fra dusinvis av AI-apprevisjoner jeg har utført for kunder.
- All konfigurasjon via miljøvariabler. Ingen hardkodede URL-er, nøkler eller hemmeligheter i kildekoden.
- Produksjonsdatabase med indekser og tilkoblingspooling. Ikke SQLite. PostgreSQL eller MySQL med PgBouncer eller innebygd pooler.
- HTTPS overalt, sikkerhetsheadere satt. Ingen blanding av HTTP og HTTPS. CSP, HSTS, X-Frame-Options.
- Row Level Security / personvernregler aktivert. Hver bruker ser bare sine egne data.
- Error boundaries på frontend, global feilbehandler på backend. Ingen feil kan stille sluke data.
- Rate limiting på alle offentlige endepunkter. Beskyttelse mot misbruk og DDoS.
- CI/CD-pipeline med automatiserte tester. Hver push testes før distribusjon.
- Overvåkning og varsling (Sentry, CloudWatch). Du vet om feil før brukerne begynner å skrive.
- Belastningstestet med realistisk trafikk. 100 samtidige brukere, ikke én.
- Staging-miljø som speiler produksjon. Test på en kopi av produksjon, ikke localhost.
- Databasemigrasjonsstrategi. Du planlegger skjemaendringer, gjør dem ikke ad hoc.
- Backup- og katastrofegjenopprettingsplan. Hva skjer når databasen går ned? Har du et svar?
Vanlige spørsmål
Hvorfor fungerer alt perfekt på localhost?
Fordi localhost er et perfekt miljø: same-origin (ingen CORS), null nettverkslatens, dev-modus maskerer advarsler, du er den eneste brukeren (ingen race conditions, ingen belastning). I produksjon er hvert av disse vilkårene annerledes — og hvert av dem kan forårsake en feil.
Hva er den vanligste produksjonsfeilen?
Manglende miljøvariabler og hardkodet konfigurasjon. Det er trivielt, men det står for hoveddelen av «fungerer lokalt, feiler i produksjon»-problemene. .env-filen din har nøkler — produksjonsserveren har dem ikke. AI hardkoder URL-er i kildekoden i stedet for å bruke miljøvariabler.
Hvordan vet jeg om appen min er produksjonsklar?
Enkelt spørsmål: hvis du ikke kan svare på «hva skjer når X feiler?» for hver kritisk sti, er appen din ikke klar. Hva skjer når databasen er utilgjengelig? Når Stripe-API-et returnerer en feil? Når 100 brukere klikker «Kjøp» i samme sekund? Hvis du ikke har svar — har du arbeid å gjøre.
Bør jeg skrive om fra bunnen av?
Vanligvis ikke. Start med en revisjon. Identifiser kritiske mangler (sikkerhet, database, konfigurasjon). Fiks dem punkt for punkt. En fullstendig omskriving gir bare mening når arkitekturen er fundamentalt feil — men i de fleste tilfeller kan du fikse eksisterende kode iterativt uten å miste arbeidet som allerede er gjort.
Kan jeg distribuere til Vercel/Netlify og kalle det produksjon?
Plattform er ikke lik produksjonsklar. Vercel og Netlify er flotte hostingverktøy, men hosting alene er ikke «produksjon». Du trenger fortsatt riktig CORS-konfigurasjon, overvåkning, feilhåndtering, sikkerhet, en skikkelig database og belastningstesting. «Deploy»-knappen er begynnelsen, ikke slutten.
Appen din fungerer lokalt, men feiler i produksjon?
Jeg hjelper deg med å identifisere og fikse hvert av disse problemene. Revisjon, fiks, distribusjon — fra prototype til produksjon.
Bestill en gratis samtale →