What Actually Breaks When You Deploy an AI-Built App: The Hidden Costs of Vibe Coding

Introduction

The term "vibe coding" — coined by AI researcher Andrej Karpathy in early 2025 — describes a new programming paradigm where developers describe what they want in natural language and let large language models (LLMs) generate the code. The appeal is obvious: you can go from an idea to a functioning application in hours, not weeks. Many startups and individuals have embraced this approach, building everything from simple landing pages to complex data pipelines with minimal manual coding.

But the party doesn’t last long. The moment you try to deploy that AI-built app to production, the real problems surface. The code that ran perfectly on your local machine suddenly fails. Dependencies are missing. Security holes are exposed. The API call that the AI invented never existed. The application crashes under load. The code is unreadable and impossible to extend.

This article dissects the specific failure modes that emerge when you deploy code written by AI — and offers practical strategies to avoid them. Whether you are a solo founder, a team lead, or a curious developer, understanding these pitfalls is essential to making vibe coding work in production.

1. The Broken Dependency Chain

One of the first things to break is the dependency tree. AI models are trained on snapshots of the internet, often months or years old. When they generate a package.json, requirements.txt, or Gemfile, they frequently pin versions that no longer exist or have breaking changes.

Example: During a recent project, I asked an AI to build a Node.js server with Express and MongoDB. It generated a package.json with "mongoose": "^6.0.0". The latest Mongoose at that time was version 8.x. The AI had no awareness of the current release cycle. Running npm install produced a different version than expected, causing subtle incompatibilities.

More alarmingly, AI can hallucinate packages. In a well-documented incident, a developer found their AI-generated code included python-magic-bin for file type detection — a package that does not exist on PyPI. The deployment pipeline failed until the error was traced to a non-existent library.

Issue AI Behavior Real-World Consequence Mitigation
Version pinning Pins outdated or non-existent versions Build failures, runtime incompatibilities Use lockfiles (package-lock.json, poetry.lock) and run npm audit
Missing packages Omits necessary dependencies Import errors at startup Generate Dockerfile with explicit install steps
Phantom packages Invents packages from training data Module not found errors Always verify package names against official registries

Recommendation: Never trust a generated dependency file. Run npm update or pip freeze to lock actual versions. Use tools like Dependabot or Renovate to stay current.

2. Security Vulnerabilities Born from AI

Security is the most dangerous area where AI-generated code breaks. Multiple studies — including a 2022 paper from Stanford University evaluating OpenAI's Codex — found that AI-generated code contains security vulnerabilities in a significant portion of cases. Common flaws include:

  • SQL Injection: AI often concatenates user input directly into SQL queries instead of using parameterized queries.
  • Command Injection: Generated shell scripts may pass unsanitized input to os.system() or subprocess.call().
  • Hardcoded Secrets: API keys, database passwords, and tokens appear directly in the code.
  • Insecure Deserialization: AI may use pickle.load() on untrusted data.

Real case: A developer used ChatGPT to write a Flask endpoint for file upload. The AI returned:

@app.route('/upload', methods=['POST'])
def upload():
    filename = request.form['filename']
    filepath = '/data/' + filename
    # ... save file

This allowed path traversal via ../etc/passwd. The vulnerability wasn't caught until a penetration test.

Reference: The OWASP Top 10 (2021) lists injection as the number one risk. AI code is particularly prone to this because it mimics patterns found on public forums, many of which are years old and insecure.

Recommendation: Run static analysis tools (Semgrep, SonarQube) on every AI-generated code block. Never deploy without a security review. For sensitive operations like payments or authentication, use validated libraries rather than AI-generated logic.

3. Hallucinated APIs and Non-Existent Features

LLMs are trained to predict the next token, not to verify facts. This leads to a phenomenon where the model invents function signatures, method names, or even entire API endpoints that do not exist in the real SDK.

Example: When integrating a payment gateway, I asked an AI to charge a customer using Stripe. It generated:

stripe.Charge.create(
    amount=1000,
    currency='usd',
    source='tok_visa',
    metadata={'order_id': '123'}
)

At the time of writing, the actual Stripe API uses stripe.PaymentIntent.create() with a different parameter structure. The AI's code would fail with an AttributeError because stripe.Charge no longer exists in the latest Stripe SDK.

Why this happens: The training data includes many different versions of API documentation. The model pieces together fragments from older and newer sets, creating a hybrid that never existed.

Real impact: A SaaS startup reported losing two weeks of development time because their AI-generated code was calling a method on the AWS SDK that was deprecated and had been removed. They thought their environment was misconfigured, but the actual problem was the AI hallucinating.

Recommendation: Always cross-reference generated API calls with official documentation. Use integration platforms that validate endpoints against live schemas. For instance, ASI Biont supports integration with Stripe via API — more at asibiont.com/courses. This ensures that any generated code is verified against real, current API contracts before deployment.

4. Performance and Scalability Blind Spots

AI models are not trained to think about performance. They generate code that is syntactically correct but often algorithmically naive. Common issues:

  • N+1 Queries: AI frequently writes ORM queries in loops, triggering hundreds of database calls when one JOIN would suffice.
  • Synchronous Blocking: Generated async code (e.g., Node.js) may use sleep() instead of proper promises, blocking the event loop.
  • No Caching: AI will recompute expensive operations repeatedly without any caching layer.
  • Memory Leaks: AI-generated code often lacks proper cleanup of file handles, network connections, or streams.

Example: An AI-built Django REST API for a social media app loaded all user posts efficiently — but then used a Python for loop to filter them instead of letting the database do the filtering. Under load (500 concurrent users), the app crashed with memory exhaustion.

Anti-Pattern AI Code (Simplified) Correct Approach
N+1 queries for user in users: posts = Post.objects.filter(user=user) Post.objects.select_related('user').all()
No caching def get_data(): return expensive_api_call() Add @cache(ttl=300) or use Redis
Sync in async await asyncio.sleep(5) (but actually time.sleep(5)) Use asyncio.sleep() consistently

Recommendation: Profile your AI-generated code under realistic load before deployment. Use tools like Apache JMeter or k6 for load testing. If the AI produces a loop over a database query, refactor it immediately.

5. The Maintainability Crisis

Vibe coding produces code that works — until you need to change it. The output is often a monolithic, uncommented, and inconsistently styled mess. Common complaints:

  • No error handling: AI skips try/except blocks, assuming perfect input.
  • Over-engineering: The AI may produce a factory pattern for a two-line function.
  • Inconsistent naming: getUser, fetch_user, and retrieveUser all appear in the same file.
  • Dead code: Functions that are defined but never called.

Real example: A colleague asked an AI to build a data transformation pipeline for CSV files. The output was a single 2000-line function with deeply nested conditionals. Changing a single column name required tracing through 15 levels of indentation. The entire pipeline was rewritten within a month.

The “works on my machine” trap: The AI often generates configuration that is environment-specific — absolute paths, hardcoded ports, or system-specific commands. These fail in a CI/CD pipeline or on a different OS.

Recommendation: Enforce a strict linter (ESLint, Pylint) and formatter (Black, Prettier) on all AI-generated code. Review it like you would a junior developer’s pull request. Require documentation comments for any non-obvious logic. Break long functions into smaller, testable units.

6. The Testing Gap

AI rarely generates comprehensive tests. When it does, they are often superficial, mocking everything and testing nothing meaningful. The typical AI unit test:

def test_add():
    result = add(2, 3)
    assert result == 5

This passes trivially. But the AI never tests edge cases: negative numbers, large integers, non-integer input, or floating point precision. Integration tests are even rarer.

Why this matters: Without tests, you cannot refactor the AI-generated code safely. Any change risks breaking something that worked. Over time, the code becomes untouchable.

Recommendation: Use AI to suggest test cases, but write the actual tests by hand. Focus on edge cases, error paths, and integration with external services. Consider property-based testing (e.g., Hypothesis for Python) to uncover hidden bugs.

7. Deployment and Operations Oversights

AI-generated code typically stops at the application logic. It ignores everything needed to run the app reliably in production:

  • No Dockerfile or container configuration – the app is built as a single process expected to run directly.
  • Missing environment variable management – secrets are hardcoded or assumed from env without default fallbacks.
  • No logging – errors are silently swallowed or printed to stdout without structure.
  • No health checks – the app offers no /health endpoint for load balancers or orchestration systems.
  • No graceful shutdown – killing the process may leave transactions open or data corrupted.

Example: An AI-generated microservice for image processing had no error logging. When deployed to Kubernetes, it started crashing every 30 minutes. The logs showed nothing. The team spent two days adding structured logging (using AWS CloudWatch or similar) before discovering an unhandled exception for oversized images.

Recommendation: After generating the application code, explicitly ask the AI to generate a Dockerfile, environment variable template, and configuration for your monitoring stack. Then, manually add health checks and graceful shutdown handlers using best practices from your runtime (e.g., Flask’s signal handlers, Node’s process.on('SIGTERM')).

Conclusion: Vibe Coding Needs Guardrails

AI-built apps are not inherently broken — but they are incomplete. The prompt-to-production pipeline has many gaps that only human expertise can fill. The real cost of vibe coding is not the time saved building, but the time lost debugging, securing, and hardening the output.

To succeed with AI-generated code, adopt these practices:

  1. Treat AI as a junior developer – never deploy its code without review.
  2. Automate the boring stuff – use linters, static analysis, and security scanners.
  3. Verify every external dependency and API call against official sources.
  4. Write tests first – or at least write them immediately after generation.
  5. Always run a performance load test before going live.

Vibe coding is here to stay. It unlocks incredible speed for prototyping and even production use. But the apps that survive deployment are the ones built with discipline — using AI as a powerful accelerator, not a replacement for engineering fundamentals.

If you are integrating multiple services into your AI-built app, platforms like ASI Biont can help manage the complexity of API connections and validation. But no tool will save you from skipping the hard work of quality assurance. The future belongs to those who master both the art of prompting and the science of deployment.

← All posts

Comments