Client-side bundles are shipped to every visitor's browser and are trivially readable via devtools — anything inlined at build time is public. When a 'use client' component references process.env.STRIPE_SECRET_KEY, Next.js, Vite, and Astro all silently replace the unprefixed reference with undefined at bundle time, which feels like a safety net but isn't: the moment someone renames the var to match the public prefix (often to fix a "why is this undefined?" bug), the secret ships to the browser. AI coding tools are particularly prone to this pattern because they don't reliably distinguish server from client context and often reach for process.env by habit on both sides of the boundary. The check catches the architectural mistake before it becomes a leak.
High because the current runtime behavior (undefined substitution) only hides the bug, not the design flaw — one rename during debugging promotes the issue to an instant credential leak in the next deploy.
Anything safe to expose to the browser (publishable keys, public URLs) should be prefixed. Anything sensitive (secret keys, database URLs, service-role keys) must NEVER be referenced client-side — move that logic to a server action, route handler, or API route.
Deeper remediation guidance and cross-reference coverage for this check lives in the security-hardening Pro audit — run that after applying this fix for a more exhaustive pass on the same topic.
project-snapshot.secrets.public-prefix-only-in-clienthighprocess.env.X reference in client-side files. Client-side files include any .tsx/.jsx file that does not start with 'use server', anything in app/_components/* or components/* that is rendered on the client, and anything imported from those. For Next.js, the public prefix is NEXT_PUBLIC_; Vite uses VITE_; Astro uses PUBLIC_. Count every reference and classify each as prefixed or unprefixed.process.env.X references in client code use the framework's public prefix (NEXT_PUBLIC_/VITE_/PUBLIC_).undefined at runtime, but the leak risk if it WERE defined is high.'use client' file references process.env.STRIPE_SECRET_KEY or any obvious server-only var, even if that var is currently unset."Found N process.env references in client files; N use the public prefix (NEXT_PUBLIC_/VITE_/PUBLIC_).""3 unprefixed env vars referenced from client files: STRIPE_SECRET_KEY in app/checkout/page.tsx, DATABASE_URL in components/db-status.tsx, ...".