DEV Community

Cover image for A CORS Mismatch That Broke DocMind AI on a Fresh Netlify Deploy
Urooj Fatima
Urooj Fatima

Posted on

A CORS Mismatch That Broke DocMind AI on a Fresh Netlify Deploy

Summer Bug Smash: Clear the Lineup 🐛🛹

This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry.

Project Overview

DocMind AI is a RAG-based document chatbot — you upload documents and ask questions about them, and it retrieves relevant context and generates grounded answers. The stack: FastAPI backend, Groq LLaMA 3.3 for generation, Pinecone for vector storage, HuggingFace embeddings, and a Netlify-hosted frontend, with voice input/output built on top.

Bug Fix or Performance Improvement

The backend already had CORS configured correctly in principle — CORSMiddleware was in place, scoped to a specific origin rather than a wildcard, with allow_credentials=False and an explicit method/header allowlist. That part was never the problem.

The actual bug was a domain mismatch. The frontend had been redeployed to a new Netlify site, docmindai-chatbot.netlify.app — note the hyphen — while the backend's allow_origins list still only contained the old domain, docmindaichatbot.netlify.app, without the hyphen. Two names that look almost identical at a glance, but the browser treats them as completely different origins. Every request from the new deployment was blocked before it reached the API, while the old domain kept working fine — which made it easy to miss at first, since "the app works" and "the app works from the URL I'm actually testing" turned out to be different claims.

Code

Commit: 291e6d8 — Update CORS to allow new Netlify domain

Before:

allow_origins=["https://docmindaichatbot.netlify.app"],
Enter fullscreen mode Exit fullscreen mode

After:

allow_origins=["https://docmindai-chatbot.netlify.app", "https://docmindaichatbot.netlify.app"],
Enter fullscreen mode Exit fullscreen mode

Full block, unchanged parts included for context:

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://docmindai-chatbot.netlify.app", "https://docmindaichatbot.netlify.app"],
    allow_credentials=False,
    allow_methods=["GET", "POST", "OPTIONS"],
    allow_headers=["Content-Type", "Accept"],
)
Enter fullscreen mode Exit fullscreen mode

Repo: uroojbuilds/Docmind-Ai
Live demo: docmindai-chatbot.netlify.app

My Improvements

The fix itself is a one-line addition, but the useful part was figuring out it was a CORS problem specifically, and not a broken deploy. The browser's network tab showed requests failing with no Access-Control-Allow-Origin header, while the backend logs showed nothing at all for those requests — which is the classic CORS signature: the browser blocks the request before your server code ever runs, so there's nothing to catch in a try/except or print statement. If the API were actually down, curling it directly would have failed too; instead, curl worked fine and only the browser call from the new Netlify URL failed, which pointed straight at an origin allowlist problem.

Rather than loosen the config to allow_origins=["*"] — which would have made the symptom disappear immediately — I kept the existing narrow, explicit list and just added the missing domain. The backend already had allow_credentials=False and a tight allow_methods/allow_headers list, which is good practice for a public API even without cookies in play, and a one-off deploy mismatch isn't a reason to give that up for convenience.

The lesson that's stuck with me: Netlify doesn't guarantee it'll reuse the exact site name you expect on every deploy, and a CORS allowlist has to track the actual deployed origin, not the one you assumed you'd get. Now when I redeploy the frontend, checking the live URL against allow_origins is one of the first things I verify before calling it done.

Top comments (1)

Collapse
 
merbayerp profile image
Mustafa ERBAY

Nice catch. To me, this feels less like a CORS bug and more like a configuration drift issue. The middleware was doing exactly what it was configured to do—the configuration just no longer matched the deployed environment.

One thing I’ve found helpful is treating allowed origins as deployment configuration rather than application code. That way, a frontend URL change doesn’t require a backend code change, and it reduces the chance of these “almost identical domain” problems appearing again.