We are experiencing a critical production issue where all dynamic API routes in our Next.js application are returning HTML 404 pages instead of being handled by their respective route handlers. This issue is blocking core functionality in our production application.
Problem Summary
-
Project: Metro2 Credit Reporting Software (
metro2.switchlabs.dev
) -
Issue: Dynamic API routes (e.g.,
/api/company/[id]
,/api/metro2-records/[id]
) return HTML 404 pages -
Static Routes: Working correctly (return JSON responses)
-
Local Development: All routes work perfectly (return expected JSON responses)
-
Vercel Deployment: Only dynamic routes fail with HTML 404s
Specific Examples
Working (Static Routes)
curl https://metro2.switchlabs.dev/api/auth/me
# Returns: {"error":"Not authenticated"} ✅ Correct JSON response
Broken (Dynamic Routes)
curl https://metro2.switchlabs.dev/api/company/test
curl https://metro2.switchlabs.dev/api/metro2-records/123
# Both return: HTML 404 page with "This page could not be found" ❌
Local Development (All Working)
curl http://localhost:3000/api/company/test
# Returns: {"error":"Not authenticated"} ✅ Correct JSON response
Comprehensive Troubleshooting Attempts
We have systematically attempted numerous solutions over multiple days:
1. Next.js Version Testing
-
Started with: Next.js 15.3.1 (experiencing 404s)
-
Downgraded to: Next.js 15.0.0 (404s persisted)
-
Downgraded to: Next.js 14.2.10 (404s still present)
-
Result: Issue persists across all Next.js versions
2. Parameter Syntax Variations
// Next.js 15 async syntax (tried)
export async function GET(request, context) {
const params = await context.params;
}
// Next.js 14 sync syntax (tried)
export async function GET(request, { params }) {
// direct access
}
- Result: No change in behavior
3. Runtime Configuration
// Added explicit Node.js runtime
export const runtime = 'nodejs';
- Result: No improvement
4. Middleware Configuration
-
Removed conflicting patterns: Eliminated
/superadmin/:path*
from middleware matcher -
Current matcher:
['/dashboard/:path*', '/profile/:path*', '/settings/:path*', '/admin/:path*']
-
Result: Static routes work, dynamic routes still fail
5. Supabase Client Variations
// Tried multiple client approaches
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';
- Result: No impact on route recognition
6. Git History Analysis
-
Tested known working commit:
a8e4cfc
(previously working) -
Force deployed working commit: Still returns HTML 404s
-
Conclusion: Even previously working code now fails on Vercel
Technical Evidence
Route File Structure
src/app/api/
├── auth/me/route.ts ✅ Works (static)
├── company/[id]/route.ts ❌ 404 (dynamic)
├── metro2-records/[id]/route.ts ❌ 404 (dynamic)
├── file-uploads/[id]/preview/route.ts ❌ 404 (dynamic)
└── superadmin/company/[companyId]/ ❌ 404 (dynamic)
Route Handler Example
// src/app/api/company/[id]/route.ts
export async function GET(request, { params }) {
console.log('Route handler called for:', params.id);
// This log never appears in Vercel logs
return NextResponse.json({ id: params.id });
}
Build Configuration
// vercel.json
{
"buildCommand": "npm install --legacy-peer-deps typescript @types/react @types/react-dom @types/node tailwindcss postcss autoprefixer && npx next build",
"installCommand": "npm install --legacy-peer-deps",
"functions": {
"api/*.py": { "maxDuration": 15 }
}
}
Next.js Configuration
// next.config.mjs
const nextConfig = {
reactStrictMode: true,
eslint: { ignoreDuringBuilds: true },
typescript: { ignoreBuildErrors: true },
trailingSlash: false
};
Impact Assessment
This issue is blocking critical production functionality:
-
User Authentication Flows: Company settings cannot be loaded
-
Data Management: Metro2 records cannot be accessed/updated
-
File Processing: Upload workflows are broken
-
Admin Features: Super admin impersonation is non-functional
Key Observations
-
Platform-Specific: Only affects Vercel deployment, not local development
-
Route Type Specific: Only dynamic routes affected, static routes work perfectly
-
Recent Regression: Previously working commits now fail
-
Consistent Pattern: All
[param]
routes return HTML 404s instead of route handler execution
Expected Behavior
Dynamic API routes should:
-
Execute their route handlers (GET, POST, PUT, DELETE functions)
-
Return JSON responses from the handlers
-
Generate proper error responses (401, 403, 500) as JSON
Actual Behavior
Dynamic API routes:
-
Never execute route handlers
-
Return HTML 404 pages with “This page could not be found”
-
Behave as if the route files don’t exist
Environment Details
-
Framework: Next.js 14.2.10 (also tested with 15.x)
-
Node Version: As configured by Vercel
-
Build Command: Custom with legacy peer deps
-
Deployment: Automatic via GitHub integration
-
Domain: Custom domain with proper DNS configuration
Request for Support
Given the comprehensive troubleshooting we’ve performed and the evidence that this is a Vercel-specific issue, we need urgent assistance to:
-
Identify the root cause of dynamic route handling failure
-
Restore functionality for our production application
-
Prevent future occurrences of this issue
We suspect this may be related to:
-
Recent changes in Vercel’s Next.js runtime handling
-
Build process modifications affecting dynamic route generation
-
Function deployment configuration for dynamic routes
This is a production-critical issue affecting our live application serving paying customers.
Thank you for your urgent attention to this matter.
Best regards,
[Your Name]
[Your Company]
[Contact Information]
Additional Context Available Upon Request:
-
Complete build logs
-
Detailed error traces
-
Repository access for investigation
-
Live debugging session availability