Error library · An AI key in the browser
OpenAI or Anthropic API called from the browser
Your app's AI feature has stopped working: OpenAI is refusing requests because the account hit its rate limit or ran out of credit. It's also calling OpenAI straight from your visitors' browsers, which means your secret API key is visible to anyone who opens the page.
Who it affects
Everyone using the AI feature gets an error instead of an answer — 5 sessions so far. Anyone could also copy your key and spend your credit.
Numbers here are from an example app where 5 visitors hit it. How serious: Critical — it stops people using the app, or costs you money.
How to fix it
Give this to the AI that builds your app. It’s the prompt Vigilia writes for this error — shown here for an example app (an orders table, a /checkout page); for your app, Vigilia fills in the real details from what your visitors hit.
For Lovable
Lovable: Bug: the app calls OpenAI directly from the browser and gets HTTP 429.
Evidence: "POST https://api.openai.com/v1/chat/completions failed with HTTP 429", request to https://api.openai.com/v1/chat/completions (HTTP 429) — seen 12 times across ~5 sessions, on /checkout.
What to change:
1. Move every call to OpenAI into a Supabase Edge Function (or your backend) that keeps the API key in a server-side secret. The browser calls that function; it never sees the key.
2. Remove the key from all front-end code and front-end environment variables (anything bundled into the browser, such as VITE_ or NEXT_PUBLIC_ variables).
3. Treat the old key as leaked: create a new one in the OpenAI dashboard and revoke the old one.
4. Check the OpenAI account's billing and limits, and when the provider says "too many requests", show the user a friendly "busy, try again in a moment" instead of an error.
Acceptance criteria: the AI feature works on the live site, no request from the browser goes to api.openai.com, and the API key appears nowhere in the page's JavaScript.For Bolt
Bolt: Bug: the app calls OpenAI directly from the browser and gets HTTP 429.
Evidence: "POST https://api.openai.com/v1/chat/completions failed with HTTP 429", request to https://api.openai.com/v1/chat/completions (HTTP 429) — seen 12 times across ~5 sessions, on /checkout.
What to change:
1. Move every call to OpenAI into a Supabase Edge Function (or your backend) that keeps the API key in a server-side secret. The browser calls that function; it never sees the key.
2. Remove the key from all front-end code and front-end environment variables (anything bundled into the browser, such as VITE_ or NEXT_PUBLIC_ variables).
3. Treat the old key as leaked: create a new one in the OpenAI dashboard and revoke the old one.
4. Check the OpenAI account's billing and limits, and when the provider says "too many requests", show the user a friendly "busy, try again in a moment" instead of an error.
Acceptance criteria: the AI feature works on the live site, no request from the browser goes to api.openai.com, and the API key appears nowhere in the page's JavaScript.For Cursor
Cursor: Bug: the app calls OpenAI directly from the browser and gets HTTP 429.
Evidence: "POST https://api.openai.com/v1/chat/completions failed with HTTP 429", request to https://api.openai.com/v1/chat/completions (HTTP 429) — seen 12 times across ~5 sessions, on /checkout.
What to change:
1. Move every call to OpenAI into a server-side route or function (for example an API route or an edge function) that keeps the API key in a server-side secret. The browser calls that function; it never sees the key.
2. Remove the key from all front-end code and front-end environment variables (anything bundled into the browser, such as VITE_ or NEXT_PUBLIC_ variables).
3. Treat the old key as leaked: create a new one in the OpenAI dashboard and revoke the old one.
4. Check the OpenAI account's billing and limits, and when the provider says "too many requests", show the user a friendly "busy, try again in a moment" instead of an error.
Acceptance criteria: the AI feature works on the live site, no request from the browser goes to api.openai.com, and the API key appears nowhere in the page's JavaScript.For Claude Code
Claude Code: Bug: the app calls OpenAI directly from the browser and gets HTTP 429.
Evidence: "POST https://api.openai.com/v1/chat/completions failed with HTTP 429", request to https://api.openai.com/v1/chat/completions (HTTP 429) — seen 12 times across ~5 sessions, on /checkout.
What to change:
1. Move every call to OpenAI into a server-side route or function (for example an API route or an edge function) that keeps the API key in a server-side secret. The browser calls that function; it never sees the key.
2. Remove the key from all front-end code and front-end environment variables (anything bundled into the browser, such as VITE_ or NEXT_PUBLIC_ variables).
3. Treat the old key as leaked: create a new one in the OpenAI dashboard and revoke the old one.
4. Check the OpenAI account's billing and limits, and when the provider says "too many requests", show the user a friendly "busy, try again in a moment" instead of an error.
Acceptance criteria: the AI feature works on the live site, no request from the browser goes to api.openai.com, and the API key appears nowhere in the page's JavaScript.For any other tool
Bug: the app calls OpenAI directly from the browser and gets HTTP 429.
Evidence: "POST https://api.openai.com/v1/chat/completions failed with HTTP 429", request to https://api.openai.com/v1/chat/completions (HTTP 429) — seen 12 times across ~5 sessions, on /checkout.
What to change:
1. Move every call to OpenAI into a server-side route or function (for example an API route or an edge function) that keeps the API key in a server-side secret. The browser calls that function; it never sees the key.
2. Remove the key from all front-end code and front-end environment variables (anything bundled into the browser, such as VITE_ or NEXT_PUBLIC_ variables).
3. Treat the old key as leaked: create a new one in the OpenAI dashboard and revoke the old one.
4. Check the OpenAI account's billing and limits, and when the provider says "too many requests", show the user a friendly "busy, try again in a moment" instead of an error.
Acceptance criteria: the AI feature works on the live site, no request from the browser goes to api.openai.com, and the API key appears nowhere in the page's JavaScript.Vigilia catches this automatically
When this happens on your live app, Vigilia recognises it at once — no waiting, no AI credits — tells you who it affects, hands your AI the fix, and confirms it held with real visitors.