Migrating AI Project Tracking System to Vercel
Fixing the dreaded "invariant HTML in an API route" error when moving from Cloudflare to Vercel
We begrudgingly migrated our Project Tracker's deploy from Cloudflare to Vercel. Here's why and what we learned along the way.
Why We Migrated
This wasn't a casual platform switch - it was driven by a specific technical roadblock:
- OpenNext/Cloudflare compiler issues producing the dreaded "invariant HTML in an API route" error
- Next.js route handlers failing in production despite working in development
The migration was focused and tactical - solving the compile errors while maintaining our architecture.
Architecture Overview
Our project management chat system isn't just a chatbox. It's a complex integration of:
- Frontend Interface: React components using AI SDK for real-time streaming
- Backend API Layer: Next.js API routes handling authentication and messages
- Tool Integration: Dynamic tool discovery with MCP Worker connections
- API Integration: 'Acting As' token handling allows our MCP Worker to interact ONLY with data within our users' scope
The Real Migration Story
The migration was more straightforward than we initially thought:
- Fixed API route handlers: Simple adjustments to prevent the "invariant HTML" errors
- Small webpack tweaks: Added proper CommonJS/ESM handling for Node.js built-ins
- Nuked Wrangler config: Removed Cloudflare worker-specific configuration
- Migrated Environment Vars: Moved over the secrets necessary for our business to work
No complex architecture changes were needed - just targeted fixes to address the specific compiler errors.
Debugging the Issue (Cloudflare)
The migration required methodical isolation:
Root Cause:
# Error in Cloudflare logs Error: Invariant: HTML functionality was requested but not enabled
Test Case:
- Created a minimal reproduction in a clean environment by running the Next.js app in a local
wrangler
environment - Being able to reproduce it locally meant I wasn't crazy, seeing it running fine with
next dev
but breaking when deployed - Was able to isolate it to the api/chat route that consumes the Vercel AI SDK (component/API route), while the rest of the app was running just fine
- Ran the local
vercel
environment as a production build and itjust worked
- Created a minimal reproduction in a clean environment by running the Next.js app in a local
The Results
It seems that a part of the OpenNext/Cloudflare translation (wherein it takes the output of next build
and re-packages it for Cloudflare compatibility) is mis-mapping... but it's difficult to isolate. Very possibly a problem within Next.js or React itself.
After the migration, we solved our critical issue:
- Deployments: Working app without the runtime "invariant HTML" error
- Development experience: No more disconnect between local dev and production behavior
- Build diagnostics: Better error messages and debugging capabilities (so much more)
The primary win was simple: our chat system actually worked in production again.
Technical Lessons Learned
For anyone dealing with Next.js Edge Runtime errors or OpenNext/Cloudflare issues:
- Be cautious with Edge Runtime + API Routes + OpenNext: This specific combination has compatibility issues
- Create minimal reproduction cases: We wasted time debugging our full app when a simple test case would have revealed the issue faster
- Runtime environment differences matter: Code working perfectly in development can still fail in production
The most important takeaway: when facing compiler issues that only appear in production, focus on build configuration first. Your actual code is probably fine.
Error Patterns to Watch For
If you're using Next.js with Edge Runtime in non-Vercel environments, watch for these specific error patterns:
# Classic "invariant HTML" error
Error: Invariant: HTML functionality was requested but not enabled.
at /node_modules/next/dist/server/base-server.js
These errors typically indicate an underlying translation/compiler issue with the build output. Thankfully, the OpenNext team is aware of it: https://github.com/opennextjs/opennextjs-cloudflare/issues/333
What's Next
This is just the beginning of our blarticles. Coming soon:
- Detailed tutorial on Cloudflare MCP Tooling
- Building resilient tool discovery systems
- Migrating back to Cloudflare (Vercel can be expensive)
Need help with your own migration? Contact us for a technical consultation.
Sometimes the most important technical migrations aren't about grand architectural changes—they're about fixing that one compiler error that's blocking everything else.
Important notes:
I will probably migrate it back to Cloudflare once this specific issue is resolved: https://github.com/opennextjs/opennextjs-cloudflare/issues/333
It's always risky binding to "not ready for production" packages, but such is the cost of pushing what's possible.
I'm currently working on improving the chat system to use a proper tRPC API path (instead of a Next.js API route) and enhancing the onboarding flow before opening up the link. If you're interested in a beta, hit me up for an invite!