Dynamic API Routes Returning HTML 404 Pages Instead of Route Handlers

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:

  1. User Authentication Flows: Company settings cannot be loaded

  2. Data Management: Metro2 records cannot be accessed/updated

  3. File Processing: Upload workflows are broken

  4. Admin Features: Super admin impersonation is non-functional

Key Observations

  1. Platform-Specific: Only affects Vercel deployment, not local development

  2. Route Type Specific: Only dynamic routes affected, static routes work perfectly

  3. Recent Regression: Previously working commits now fail

  4. Consistent Pattern: All [param] routes return HTML 404s instead of route handler execution

Expected Behavior

Dynamic API routes should:

  1. Execute their route handlers (GET, POST, PUT, DELETE functions)

  2. Return JSON responses from the handlers

  3. Generate proper error responses (401, 403, 500) as JSON

Actual Behavior

Dynamic API routes:

  1. Never execute route handlers

  2. Return HTML 404 pages with “This page could not be found”

  3. 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:

  1. Identify the root cause of dynamic route handling failure

  2. Restore functionality for our production application

  3. 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

There’s another community post with 404 debugging tips that might be helpful. Please give these solutions a try and let us know how it goes.

A human should be around soon to offer more advice. But you can also get helpful information quickly by asking v0.