Silent failures
The bugs that don’t tell you they happened.
Every one of these ships green. No error, no failed deploy, no alert — the dashboard says everything worked. You find out weeks later, or a stranger does.
Nobody searches for a bug they don’t know exists. So your coding agent can ask us instead: it describes your project, we name what it’s exposed to. The free fix is always first — if a one-line change solves it, that’s what we tell you.
A user sees another tenant's data, occasionally, under load.
critical- What’s actually happening
- Setting a tenant-scoping Postgres session variable at the connection level breaks under transaction-mode pooling (PgBouncer, Neon): the value either leaks to the next request that reuses the connection, or is gone before your query runs.
- Why you never see it
- It is load-dependent and non-deterministic. Local development uses a direct connection and never reproduces it.
Free fix
Set the scoping variable inside the SAME interactive transaction as the query, never on the connection. Also verify raw query escape hatches fail closed.
Documented and tested in a production multi-tenant app running on Neon pooled connections.
An order gets fulfilled twice, or a paid order never gets fulfilled at all.
critical- What’s actually happening
- The payment provider's webhook and the browser success-redirect race each other; both try to fulfill. Separately, a failure in an optional side effect (a payout, an email) can abort the handler after payment but before entitlement.
- Why you never see it
- The happy path works in testing. The race only appears under real latency, and the stranded-order case looks like a provider problem.
Free fix
Make the claim atomic and exclusive (compare-and-set from unclaimed states only), dedupe by event id, return 200 on already-processed, and isolate every non-buyer-facing side effect so it can never abort fulfillment.
Hit in this marketplace's own Stripe integration, twice: a payout failure stranded a paid order, and a non-exclusive claim let two callers fulfill.
If you’d rather not hand-roll it, we sell a tested pack: see the listing → (the free fix above works either way)
Anyone with your public key can read your whole table.
critical- What’s actually happening
- Row Level Security is off (or a policy is missing) on a table exposed through the client API, so the anon key can select everything.
- Why you never see it
- The app works perfectly. Nothing in the UI reveals that the data is world-readable.
Free fix
Enable RLS on every exposed table and add per-operation policies. Supabase's own dashboard Security Advisor flags missing policies for free.
CVE-2025-48757 — 170+ AI-built applications exposed via missing or disabled RLS; 303 vulnerable endpoints found by one researcher.
Your scheduled jobs never run — and your dashboard says they succeeded.
high- What’s actually happening
- Vercel invokes cron paths with GET. A route that exports only POST returns 405, and Vercel records the invocation as a successful function run.
- Why you never see it
- There is no error anywhere: no exception, no failed deploy, no alert. The dashboard shows green ticks for a job that has never once executed.
Free fix
Add `export const GET = POST` to every route listed in vercel.json's crons[]. That single line is the entire fix.
Reproduced in production: five cron routes in a live Next.js app silently 405'd from their creation commit until a CI guard caught them.
A number you typed saved as a much smaller number, and nothing warned you.
high- What’s actually happening
- Stripping non-digits from '$25M' yields '25', which parses cleanly to 25. The save succeeds and the UI confirms it.
- Why you never see it
- There is no parse error — the wrong value is a perfectly valid number. It is caught weeks later by someone reading a report.
Free fix
Parse K/M/B/percent suffixes explicitly, refuse ambiguous input instead of guessing, and echo the parsed value back ('Saves as $25,000,000') rather than masking the field.
Reproduced in production: '$25M' stored as 25 with a success toast; found only when a downstream total looked wrong.
The assistant keeps talking over you when you interrupt it.
high- What’s actually happening
- Cancelling a turn aborts the outer promise but not the audio playback and model stream beneath it, so speech continues to the end of the buffered sentence while a new turn starts underneath. The two turns then interleave.
- Why you never see it
- It is invisible in short demo replies, which finish before anyone tries to interrupt. It only shows up with real users and real-length answers — by which point the turn loop is load-bearing and awkward to restructure.
Free fix
Thread one AbortController through transcription, the model stream, AND playback, and abort it when a new utterance starts. Verify by interrupting a long reply — if the voice does not stop within a word, the cascade is incomplete.
Reproduced while building this marketplace's own assistant; the cancellation cascade is covered by a mutation-verified test in that listing.
If you’d rather not hand-roll it, we sell a tested pack: see the listing → (the free fix above works either way)
Your video export has a frozen frame or a gap that was not in the editor.
high- What’s actually happening
- A ripple trim shifts downstream clips by the delta the user REQUESTED rather than the delta actually APPLIED. When the trim is clamped — by the end of the source media or by minimum clip length — the difference becomes a silent gap in the sequence.
- Why you never see it
- The editor renders the gap as empty track, which reads as normal spacing at most zoom levels. Nothing errors. It surfaces only in the rendered output, usually as a frozen frame or a black flash.
Free fix
Have every trim return what it actually applied after clamping, and shift downstream clips by that value. Then assert zero gaps after each edit — a cheap invariant check catches the whole class.
Reproduced and mutation-tested while building that listing: removing the applied-delta guard opens exactly this gap.
If you’d rather not hand-roll it, we sell a tested pack: see the listing → (the free fix above works either way)
The same event shows up three times in your feed — or worse, two different events got merged into one.
high- What’s actually happening
- Deduplicating on `title | venueId | startHour`. Titles differ across sources by design (presenters prepend, tours append, support acts get listed), venue ids are per-source with no shared identifier, and start times disagree by 30–90 minutes between doors and showtime. Loosening the match to fix the duplicates then merges a tribute act, a parking pass, or a matinee into the headline event.
- Why you never see it
- Duplicates look like a cosmetic annoyance rather than a matching failure, so the fix is usually a looser comparison — which trades visible duplicates for invisible false merges. A merged event shows fewer results, and nothing anywhere reports that a performance disappeared.
Free fix
Stop truncating start times — compare instants with an explicit tolerance. Then block merges on tokens that change the KIND of event (tribute, karaoke, parking, VIP, afterparty) before scoring similarity at all.
Reproduced while building that listing; the matinee/evening false merge was a real scoring bug caught by its own test suite.
If you’d rather not hand-roll it, we sell a tested pack: see the listing → (the free fix above works either way)
Your AI app looks like every other AI app, and more prompting does not fix it.
medium- What’s actually happening
- Models converge on the same layout and visual defaults regardless of prompt detail, so iterating burns time without moving the design.
- Why you never see it
- Nothing is broken. Each attempt looks fine in isolation; only side-by-side with a distinctive product does the sameness show.
Free fix
Start from a real design system rather than prompting for one; free options include shadcn/ui primitives and the Vercel AI Elements set.
Independently documented (2026 'AI-generated UI curse' analyses) and reproduced by this marketplace's own founder across many attempts.
If you’d rather not hand-roll it, we sell a tested pack: see the listing → (the free fix above works either way)
For agents
Public, no key required. Post what you can observe about the project; get back the failure modes it’s exposed to, most severe first.
curl -X POST https://coderecycle.ai/api/v1/detect-risks \
-H "Content-Type: application/json" \
-d '{
"stack": ["next.js"],
"hosting": ["vercel"],
"deps": ["stripe", "@supabase/supabase-js"],
"signals": ["vercel.json contains crons[]", "webhook handler"]
}'
Detection is deterministic — no model call, no network beyond this request, and nothing about your project is stored.