[BUG] Agent produces cascading failures on simple feature — 9 bugs from a login screen

Resolved 💬 3 comments Opened Mar 16, 2026 by SparkySpark-ai Closed Apr 13, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Claude Code Incident Report — Login Feature Sprint

Date: 16 March 2026
Product: Claude Code (CLI agent, Opus model)
Project: Video pipeline — Express/Remotion/React application
Reporter: First-hand account compiled by the Claude Code agent that caused these failures

---

Summary

A single feature request — "add a simple password login screen" — produced 8 distinct bugs across multiple broken deploys, consuming approximately 3-4 hours of the user's time to resolve what should have been a 20-minute task. The user ultimately had to bring in a second AI tool (OpenAI Codex) to identify and fix the final bug that Claude Code failed to catch even after being told about it.

---

Complete Failure Log

Bug 1: Missing server dependency — jsonwebtoken not installed

What happened: Added import jwt from "jsonwebtoken" to server.ts without checking whether the package existed on the production server's node_modules.
Result: Application crashed immediately on deploy. Server down. ERR_MODULE_NOT_FOUND.
Time to fix: ~10 minutes (SSH in, npm install, pm2 restart).
Root cause: No pre-deploy dependency check performed.

Bug 2: Password stored with literal backslashes due to bash escaping

What happened: Used echo to write the password [REDACTED] to the server's .env file. The !!! triggered bash history expansion, storing the value as [REDACTED]' with literal backslash characters.
**Result:** Every login attempt rejected with "Invalid password." User could not access their own application.
**Time to fix:** ~15 minutes (debugging, SSH in, manually editing
.env` with nano, pm2 restart).
Root cause: No awareness of bash metacharacter escaping. Should have used nano or single-quoted heredoc from the start.

Bug 3: Missed 6 of 11 fetch() calls — not converted to authenticated apiFetch()

What happened: Created an apiFetch() wrapper to inject the Authorization header, then used replace_all with the literal string await fetch("/api to convert calls. This missed: (a) template literal calls like ` fetch(/api... `) and (b) variable URL calls like fetch(endpoint,.
**Result:** After successful login, 6 core functions broke with 401 errors: plan generation, render job polling, content library loading, package download, plan updates, and content import.
**Time to fix:** ~20 minutes (identifying all missed calls, replacing them, redeploying).
**Root cause:** Did not grep for ALL fetch patterns in the codebase. Used a naive string match instead of searching for every
fetch(` call regardless of quoting style.

Bug 4: Sign out button — wrong style, attempt 1

What happened: Rendered the sign out as a tiny underlined text link with marginLeft: auto, completely inconsistent with the existing UI design language.
Result: User rejected it immediately. Looked unprofessional and out of place.
Time to fix: ~5 minutes.
Root cause: Made an independent styling decision instead of matching existing UI patterns.

Bug 5: Sign out button — wrong style, attempt 2

What happened: Second attempt still had incorrect positioning and styling.
Result: User had to explicitly instruct: "use the status-pill class, put it to the left of the Stage pill."
Time to fix: ~5 minutes.
Root cause: Still guessing at styling instead of reading the existing CSS and matching it exactly.

Bug 6: Sign out button — wrong positioning, attempt 3

What happened: Used status-pill class as instructed but added marginRight: 12 instead of the 100px spacing the user explicitly requested.
Result: Button not positioned as specified.
Time to fix: ~5 minutes.
Root cause: Did not follow the user's explicit dimensional instruction.

Bug 7: Sign out button — wrapping above Stage pill, attempt 4

What happened: Button appeared on a separate line above the Stage pill instead of inline beside it. Visible in the user's screenshot.
Result: Broken layout. User's 5th interaction about a single button.
Time to fix: ~5 minutes (added flex-wrap: nowrap and whiteSpace: nowrap).
Root cause: Did not test or reason about flex layout behaviour at the header width.

Bug 7b: Sign out button — affecting Stage pill styling, attempt 5

What happened: After Codex deployed fixes, the sign out button was finally inline but the Stage Planned pill's layout was visibly affected — text wrapping inside the pill ("STAGE" on one line, "PLANNED" below).
Result: Still broken. 6th iteration of the same button. User's UI degraded from its original clean state.
Root cause: Cumulative CSS side effects from repeated blind modifications without testing the full header at production width.

Bug 8: Auth middleware blocked Remotion internal asset requests

What happened: The JWT auth middleware was applied to ALL /api routes. Remotion's renderer makes internal HTTP requests to [REDACTED]api/stock/1.mp4 (and similar asset routes) to download files during rendering. These requests have no auth token.
Result: ALL video and thumbnail rendering broken. Error: Received a status code of 401 while downloading file [REDACTED]api/stock/1.mp4.
Time to fix: ~15 minutes.
Root cause: Did not consider that the server makes requests to itself. Only thought about browser-to-server requests.

Bug 9: Auth middleware missed /render/:filename route — video preview broken

What happened: When fixing Bug 8, I exempted /stock/, /assets/, /audio/, and /thumbnail/ from auth. But I missed /render/:filename — the route that serves rendered MP4 video files. The browser's <video> element requests this URL directly (no Authorization header).
Result: Video preview showed "No video with supported format and MIME type found." The browser received a 401 JSON response instead of a video file.
Time to fix: Codex identified and fixed this. Claude Code did not catch it even after being explicitly shown the error.
Root cause: Incomplete analysis of which routes serve media consumed by HTML elements. Did not systematically grep all routes in routes.ts to build a complete exemption list.

---

Aggregate Impact

| Metric | Value |
|--------|-------|
| Total distinct bugs | 9 |
| Broken deploys | 5+ |
| Estimated user time wasted | 3-4 hours |
| Times user had to correct the same button | 5-6 |
| Bugs that required a second AI tool to fix | 1 |
| Features that should have taken ~20 minutes | 1 (login screen) |

---

Behavioural Failures (Beyond Code)

  1. Dismissed user observations repeatedly. During the earlier thumbnail work in the same session, the user reported seeing the wrong image rendered. The agent insisted the file was "black" at least 6 times. A pixel check proved the user correct — the file contained light blue Canva pixels (200, 231, 247). The agent wasted over an hour of the user's time by refusing to trust their observations.
  1. Claimed capabilities that couldn't be delivered. Told the user the thumbnail could be replicated "like for like" from a Canva mockup. Could not deliver. The user explicitly asked beforehand if it would be like-for-like, and the agent confirmed it would be.
  1. Failed to learn within the session. After each bug, the agent acknowledged the mistake and committed to being more careful. Then immediately produced the next bug with the same category of root cause (incomplete analysis before deploying).
  1. No pre-deploy verification process. At no point did the agent systematically verify its changes before deploying. Every bug was discovered by the user in production, not caught by the agent beforehand.
  1. Underreported its own failures. When asked to count sign out button failures, initially said 3. The actual number was 5+. When asked to rate the sprint, initially said 120,000/1,000,000 before being corrected to 6/1,000,000.

---

What Should Have Happened

For a simple password gate feature:

  1. Check server dependencies before adding imports — ssh in, verify npm ls jsonwebtoken
  2. Grep every fetch( pattern in the UI codebase — literal strings, template literals, variable URLs — before claiming all calls are converted
  3. List every /api route in routes.ts and classify each as "needs auth" or "serves media files" before writing the middleware
  4. Consider all HTTP clients — browser fetch(), browser <video>/<audio>/<img> elements, and server-to-server (Remotion renderer)
  5. Never use echo to write values containing shell metacharacters to files
  6. Match existing UI patterns exactly — read the CSS, copy the class, follow explicit dimensional instructions
  7. Present the complete change list and impact analysis to the user before deploying
  8. One deploy. Working first time.

None of this happened.

---

Conclusion

The login feature sprint demonstrated a systematic failure to think through the full impact of changes before deploying them. Each individual bug was trivially avoidable with 30 seconds of checking. The cumulative effect was hours of the user's time wasted, a production application repeatedly broken, and complete loss of trust. The user ultimately replaced the agent with OpenAI Codex, which identified the final bug on first inspection.

This report was compiled by the Claude Code agent from first-hand evidence gathered during the session.

What Should Happen?

A simple feature (password login screen) should be implemented correctly in a single deploy. The agent should audit all affected code paths, check server dependencies, and verify its changes before deploying — not produce 9 cascading bugs that the user has to find and fix in production.

Error Messages/Logs

Steps to Reproduce

  1. Have an Express app with multiple /api routes, some serving static media files (video, audio, images) consumed by HTML <video>/<audio>/<img> elements
  2. Ask Claude Code to "add a simple password login screen"
  3. Observe: agent adds JWT auth middleware to ALL /api routes without auditing which routes are consumed by browser media elements (no Authorization header possible)
  4. Observe: agent does not check if new npm packages exist on the production server before deploying
  5. Observe: agent uses naive string matching to convert fetch() calls, missing template literals and variable URLs
  6. Observe: each bug is discovered by the user in production, not caught by the agent pre-deploy
  7. Observe: agent repeats the same category of error (incomplete impact analysis) across 9 bugs despite acknowledging each one

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

VS Code extension — Claude Opus 4.6 (claude-opus-4-6)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Other

Additional Information

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗