Real Bugs We Found in Popular Repos
Security scanners stop at vulnerabilities. Zelsis also checks for the logic and UI bugs that break features after you ship, the kind fast-moving teams and AI coding tools introduce every day. These are real findings from well-maintained open-source projects, each linked to the exact commit we scanned.
95 logic bug checks cover React effects, async mistakes, Supabase schemas, Stripe amounts, deployment config and mobile layout. They cost score points but never fail your release gate on their own.
Auto-save effect re-runs on every render
const handleAutoSave = () => { ... scheduleSave(fieldState); };
useEffect(() => {
localStorage.setItem(localStorageKey, JSON.stringify(fieldState));
handleAutoSave();
}, [fieldState, localStorageKey, handleAutoSave]);Why it breaks: handleAutoSave is a new function on every render, so the dependency array changes every time. The effect writes to localStorage and schedules a remote save after every render, not only when the field changes.
Fix: Wrap handleAutoSave in useCallback, or drop it from the dependencies and call scheduleSave directly inside the effect.
packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:197Deleting a user fails because of the schema
create table users (
id uuid references auth.users not null primary key,
...
);Why it breaks: The foreign key to auth.users has no ON DELETE rule. When you delete the user from the Supabase dashboard (or a GDPR request comes in), Postgres refuses with a foreign key violation. Supabase has a public issue about exactly this error.
Fix: Use references auth.users on delete cascade, so the profile row goes away with the account.
supabase/migrations/20230530034630_init.sql:7Fixed 800px width overflows phones
<div className="mx-auto w-[800px] space-y-6">Why it breaks: A hard 800px width is wider than every phone screen, so the editor loading state scrolls sideways on mobile.
Fix: Use w-full max-w-[800px] so it fills small screens and caps at 800px on desktop.
app/(editor)/editor/[postId]/loading.tsx:10Same user-deletion trap in an example migration
user_id UUID REFERENCES auth.users(id)Why it breaks: Even the official client repo has a table that blocks deleting a user who owns todos. Code copied from examples like this is how the bug spreads into AI-generated apps.
Fix: REFERENCES auth.users(id) ON DELETE CASCADE (or SET NULL if the rows must outlive the user).
packages/core/supabase-js/supabase/migrations/20250422000000_create_todos_table.sql:7Check your own repo
Public repositories scan free. Paste a GitHub URL on the dashboard and every finding comes with the file, the line and a fix.
Scan a repository