I spent hours wondering why my MongoDB documents only had an
_idfield after saving β and the fix turned out to be ridiculously simple.
If you're using Mongoose with the Next.js App Router and noticing that only the _id is being saved to MongoDB (while fields like name, email, createdAt, and updatedAt are mysteriously missing), this article is for you.
I'll walk you through the exact bug, what caused it, and how to fix it in 3 seconds β before it wastes as much of your time as it did mine.
π§ The Stack
I was building a simple signup API
- [Nextjs 13]
- MongoDB (via Mongoose)
- Thunder Client (for testing)
- App Router (
/app/auth/signup)
Everything was fine... until it wasnβt and i started sweating, cussing and had to nose dive into nextjs documentation.
π¨ The Weird Bug
I sent a POST request to my /api/auth/signup route with this JSON body:
{
"name": "iamonuwacj",
"email": "iamonuwacj@example.com"
}
The Response I keep getting
{
"_id": "665eaa...",
"__v": 0
}
No name, no email, no createdAt, no updatedAt. Just _id.
But hereβs the kicker:
β
console.log(await req.json()) showed the correct data.
β
The MongoDB connection was successful.
β
No error messages were thrown.
So... why was only the _id saved?
What happened to the data I posted??
π§ *The Real Cause *
- The issue? Mongoose model caching during hot reload.
- In dev mode, when the Next.js server hot-reloads, it may:
- Recompile the same schema multiple times
- Corrupt the internal Mongoose model
- Silently break how fields are mapped and saved
In other words, my model looks fine β but Mongoose stopped applying the schema properly.
β The Fix
π 1. Restart the dev server and clear cache:
# Stop the server
Ctrl + C
# Clear the Next.js build cache
rm -rf .next
# Restart dev
npm run dev
Boom π₯. Fields started saving again, along with timestamps.
β 2. Use Defensive Mongoose Model Export
Make sure your model is exported like this to avoid duplicate declarations:
export default mongoose.models.User || mongoose.model('User', UserSchema);
This prevents Mongoose from re-declaring models when the app reloads.
π Sample example for the models /models/User.js
import mongoose from 'mongoose';
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true }
}, { timestamps: true });
export default mongoose.models.User || mongoose.model('User', UserSchema);
/api/auth/signup/route.js
import connectDB from '@/lib/db';
import User from '@/models/User';
export async function POST(req) {
try {
await connectDB();
const body = await req.json();
const { name, email } = body;
const user = new User({ name, email });
await user.save();
return new Response(JSON.stringify(blog), {
status: 201,
headers: { 'Content-Type': 'application/json' }
});
} catch (err) {
console.error("Error:", err);
return new Response(JSON.stringify({ error: 'Server error' }), {
status: 500
});
}
}
π Thunder Client Request (for testing)
- POST http://localhost:3000/api/auth/signup
- Headers: Content-Type: application/json
- Body:
{
"name": "iamonuwacj",
"email": "iamonuwacj@example.com"
}
β Now, It Works!
MongoDB now saved the document like this:
{ "_id": "665eaa...", "name": "iamonuwacj", "email": "iamonuwacj@example.com", "createdAt": "2025-06-13T18:55:23.123Z", "updatedAt": "2025-06-13T18:55:23.123Z", "__v": 0 }
π§ Takeaways
- When using Mongoose + Next.js App Router, always:
- Export models defensively
- Clear .next cache if things act weird
- If only _id is saved:
- Your schema isn't applied correctly
- You're likely using a stale or broken model
Have You Faced This?
Let me know if this saved your day (or night)!
I would love to hear your Mongoose war stories
Happy debugging
Top comments (0)