I spent hours wondering why my MongoDB documents only had an
_id
field 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)