All 20 checks with why-it-matters prose, severity, and cross-references to related audits.
Handlers that return hardcoded fake data silently lie to every caller. Users see a populated list named "John Doe" with email "john@example.com" and assume the product is wired up, so the defect escapes QA, reaches paying customers, and often surfaces only after launch when real accounts should exist. Marketing dashboards, onboarding flows, and integration partners all pull from the mock and make wrong decisions. The placeholder-hygiene taxon exists because these fabrications corrupt trust long before they trigger an observable error.
Why this severity: Critical because fake data in a live handler actively misleads users and downstream systems with zero error signal.
ai-slop-half-finished.mock-responses.mock-data-in-handlersSee full patternIn-memory arrays as databases are the defining prototype artifact of AI-generated code. They work flawlessly in a single-process demo and fail completely the moment a second request hits a different process, the server restarts, or the platform auto-scales. Every write is silently discarded on restart — no error, no warning. Per CWE-1188 (Insecure Default Initialization), the defect is that the 'database' initializes to an empty slice of process memory rather than a durable store. Any data entered by real users — signups, orders, payments, messages — vanishes on the next deploy.
Why this severity: Critical because the data loss is total, silent, and guaranteed on every server restart, making the application functionally unusable for any production workload.
ai-slop-half-finished.mock-responses.in-memory-prod-storeSee full patternPackages like `msw`, `nock`, and `fetch-mock` intercept network traffic at the module level. If one is imported from a production route or shared client, every outbound call from that path hits the mock instead of the real backend — so payments, auth, and analytics silently no-op while returning fake success responses. The defect typically ships because AI scaffolding imports these libraries into source files while prototyping, and the import is never removed before deploy.
Why this severity: High because a single stray mock import can redirect entire subsystems to fabricated responses in production.
ai-slop-half-finished.mock-responses.mock-lib-imported-in-prodSee full patternA handler that imports `./fixtures/products.json` and returns it pretends to be a real endpoint while serving static bytes. Data never updates, writes are impossible, and the client cache treats stale fixture data as authoritative. Because the response shape looks plausible, bugs hide for weeks until a user edits a record and the change silently disappears. Fixture-backed endpoints also bypass the database entirely, so inventory counts, pricing, and permissions drift from reality immediately.
Why this severity: High because fixture-backed endpoints defeat every write path and make stale data indistinguishable from live data.
ai-slop-half-finished.mock-responses.fake-json-responsesSee full patternA handler whose body is only `return Response.json({})` or `return new Response()` returns HTTP 200 without doing anything. The client accepts it as success, moves on, and logs no error. Orders never save, refunds never queue, webhooks never acknowledge — and the failure is invisible until a customer complains or a reconciliation job runs weeks later. This pattern ships constantly when AI scaffolds a route file it never finishes wiring.
Why this severity: Medium because silent success on a non-health endpoint causes data loss without producing any observable error.
ai-slop-half-finished.mock-responses.stub-return-valuesSee full patternFallback admin credentials are a silent authentication backdoor. When a request arrives with an empty or malformed body, the OR-expression resolves to the hardcoded value — and the code proceeds to look up and authenticate a real admin account. An attacker who sends an empty POST to the login endpoint gets in as admin. This maps to OWASP A07:2021 (Identification and Authentication Failures) and CWE-1188 (Insecure Default Initialization): the default is not 'reject unauthenticated request' but 'log in as administrator.' No rate limit or firewall rule compensates for this; the bypass is baked into application logic.
Why this severity: Critical because a single unauthenticated HTTP request with an empty body can elevate to admin access, bypassing all authentication controls entirely.
ai-slop-half-finished.hardcoded-test-data.fallback-admin-credentialsSee full patternA seed script wired into `postinstall` or `scripts.start` runs on every production deployment and creates backdoor admin accounts with credentials that are publicly visible in your repository. Anyone who clones your repo — or reads your deploy logs — has the admin password. CWE-798 (Use of Hard-coded Credentials) and CWE-1188 (Insecure Default Initialization) both apply: the first deployment permanently plants known credentials in the live database, and subsequent deploys may re-upsert them if the seed is idempotent. Your security posture is now bounded by how broadly your repo can be read.
Why this severity: High because the first production deploy creates a live admin account with credentials visible in source control, giving repository readers direct admin access to the production system.
ai-slop-half-finished.hardcoded-test-data.hardcoded-test-users-in-seedSee full patternHardcoded user IDs in handlers mean the application is operating as a single-user system dressed up as multi-user software. Every POST, PATCH, or DELETE runs against the demo account's data regardless of which user is authenticated — or whether anyone is authenticated at all. This violates OWASP A01:2021 (Broken Access Control) and CWE-284 (Improper Access Control): the authorization decision has been reduced to a constant. Real users create data they cannot see, and the demo user accumulates all writes silently.
Why this severity: Medium because exploitation requires understanding the application's data model, but any authenticated user can corrupt another user's data or read the demo account's accumulated records.
ai-slop-half-finished.hardcoded-test-data.hardcoded-user-id-in-handlersSee full patternStrings like `Hello [INSERT_USER_NAME]!` or `Total: {{amount}}` render verbatim in the browser or email client. Users see the literal brackets, support tickets flood in, and the brand takes a direct credibility hit — especially in transactional email, which customers screenshot and share. This is pure placeholder-hygiene rot: the AI emitted a templating stub, no one swapped in real interpolation, and the string shipped.
Why this severity: Medium because uninterpolated placeholders damage user trust immediately but rarely cause data loss or security impact.
ai-slop-half-finished.hardcoded-test-data.placeholder-template-variablesSee full patternA hardcoded `http://localhost:3000/api` or `ws://127.0.0.1:8080` in a shipped client works on exactly one machine: the developer's laptop. Every other environment — preview deploys, staging, production — fails as soon as the code runs, usually with opaque CORS or network errors. The defect often hides until after deploy because local dev still works, so it surfaces directly to users instead of in CI.
Why this severity: Low because the break is loud and usually caught quickly in preview, but it still reaches users when config files slip past review.
ai-slop-half-finished.hardcoded-test-data.hardcoded-localhost-urlsSee full patternAuth bypass patterns collapse the entire authentication model to a single HTTP header, query parameter, or magic email suffix. Any client that knows the bypass — or that fuzzes common header names — gains admin privileges with no credentials. This is CWE-489 (Active Debug Code) combined with OWASP A07:2021 (Identification and Authentication Failures) and CWE-287 (Improper Authentication): code that was added for local convenience becomes a permanent privilege escalation vector. Unlike other patterns, even a `NODE_ENV === 'development'` guard does not neutralize the risk — environment variables are routinely misconfigured in staging and CI.
Why this severity: High because any request crafted to match the bypass condition — a header, query string, or email suffix — immediately grants admin access with no other credential required.
ai-slop-half-finished.incomplete-impl.dev-only-auth-bypassSee full patternAn empty `/api/auth/login` handler returns success without verifying credentials, so any request authenticates anyone. An empty `/api/webhooks/stripe` handler 200s and drops the event, so Stripe stops retrying and payments never reconcile. These stubs map directly to OWASP A07 (Identification & Authentication Failures) and to silent revenue loss. AI scaffolds these endpoints early to keep routes compiling; the implementation gets deferred and forgotten.
Why this severity: High because empty auth and webhook handlers bypass identity checks and silently drop critical business events.
ai-slop-half-finished.incomplete-impl.empty-critical-handlersSee full patternA `throw new Error('not implemented')` turns into an HTTP 500 the first time any caller hits that code path. Because AI generates these as scaffolding — `calculateRefund`, `sendInvoice`, `getUserBalance` — the thrown paths often sit directly on revenue-critical flows. Users encounter them during checkout, refund, or billing and abandon the transaction; the defect then masquerades as a generic 500 in observability and takes hours to trace back to the stub.
Why this severity: Medium because the failure is loud but only triggers when the specific path executes, often on a less-travelled flow.
ai-slop-half-finished.incomplete-impl.throw-not-implementedSee full pattern`if (false)` blocks are code that never executes — AI commonly uses them to 'disable' logic without deleting it, leaving dead branches that confuse static analysis, obscure actual code paths, and make security reviews unreliable. `if (true)` debug toggles expose internal state (request bodies, database rows, session tokens) to logs that may be shipped to log aggregators, error trackers, or observability platforms. CWE-489 (Active Debug Code) applies: these patterns signal that the code was never cleaned up after prototyping and likely contains other unfinished logic nearby.
Why this severity: Medium because `if (true)` blocks actively leak internal data to logs, while `if (false)` blocks signal incomplete implementation that auditors and attackers both use to locate unfinished security controls.
ai-slop-half-finished.incomplete-impl.if-false-debug-blocksSee full patternAn HTTP 501 with no explanation tells clients the endpoint exists but does nothing, with no context on when it will. Integration partners file tickets, mobile apps cache the error, and monitoring treats the response as healthy because it is a valid status code. A 501 is legitimate when documented — `// TODO(ISSUE-123): refunds require Stripe migration` — but unjustified 501s are indistinguishable from a forgotten stub.
Why this severity: Low because the response is at least an honest error, but unjustified 501s waste integrator time and hide abandoned features.
ai-slop-half-finished.incomplete-impl.return-501-not-implementedSee full patternDebug routes left without environment gates are live attack surface. They commonly dump internal state — full user tables, environment variables, session stores, database query results — to anyone who discovers them. OWASP A05:2021 (Security Misconfiguration) and CWE-489 (Active Debug Code) both cover this: the misconfiguration is shipping development tooling as production infrastructure. Discovery is trivial: common debug path patterns (`/api/debug`, `/api/test`, `/playground`) are in every web scanner wordlist, and AI-generated projects tend to follow identical naming conventions.
Why this severity: Medium because the exploitability depends on what data the route exposes, but debug routes in AI projects frequently dump database contents or internal config without authentication.
ai-slop-half-finished.dev-artifacts.debug-routes-activeSee full patternA module-scope `const DEBUG = true` survives every environment because it is never read from `process.env`. Debug logs spew into production, verbose error messages leak internal structure, `SKIP_AUTH` bypasses middleware, and `MOCK_PAYMENTS` routes real checkouts to fakes. These constants ship because AI sets them to `true` during scaffolding and never parameterizes them, and linters do not flag boolean literals.
Why this severity: Low because the flags rarely expose data directly, but they can enable debug paths, skipped checks, or mock flows in production.
ai-slop-half-finished.dev-artifacts.dev-only-env-flags-enabledSee full patternValues like `STRIPE_SECRET_KEY=your_stripe_key_here` or `DATABASE_URL=TODO` in `.env.example` waste every new contributor's onboarding time. They cannot tell which format the real value takes, whether it is a test key, or what character length to expect. The file exists specifically to bootstrap environments, so a placeholder that communicates nothing defeats its purpose and often leads developers to paste real credentials into the wrong slot.
Why this severity: Low because these are template files, but placeholder tokens still slow onboarding and risk credential misplacement.
ai-slop-half-finished.dev-artifacts.placeholder-env-valuesSee full patternA bare `if (process.env.NODE_ENV === 'development') { console.log(state) }` with no else branch marks code as dev-only but ships it anyway — the gate evaluates at runtime, not build time, so the branch stays in the production bundle and fires for anyone whose `NODE_ENV` is misconfigured. More often it is just dead clutter left behind from debugging sessions, and it signals poor code-quality hygiene across the repo.
Why this severity: Low because the impact is mostly bundle bloat and noise, but clustered markers indicate broader cleanup gaps.
ai-slop-half-finished.dev-artifacts.unused-esbuild-markersSee full patternA `<button disabled>Coming Soon</button>` announces unfinished work on every page view. Prospects see the placeholder before they see the working feature set, pricing tables look padded with vaporware, and competitors screenshot the dead CTA for comparison pages. The pattern also breaks keyboard and screen-reader flows because the button focuses but does nothing, which maps to WCAG 2.2 SC 2.4.3 (Focus Order) and SC 3.2.2 (On Input) complaints.
Why this severity: Info because the defect is cosmetic and accessibility-adjacent rather than data- or security-impacting.
ai-slop-half-finished.dev-artifacts.disabled-feature-placeholdersSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open WIP-in-Production Audit