Troubleshooting
TypeScript: db.users does not exist / is any
Cause: schemas array not as const, or schemas not passed to createClient.
export const schemas = [userSchema] as const; // required
const connect = createClient({ serverless: true, schemas });Use SchemasToClient<typeof schemas> for shared types.
ZodError on create
Common causes:
- Missing
.required()field - Invalid email/url/pattern
- Wrong type (string vs number)
- Enum value not in list
Inspect error.issues for path and message.
Defaults only apply when the field is missing and validation mode is not off.
Update rejected but $inc works
Only plain objects and $set / $setOnInsert are validated.
If $set: { age: -1 } fails min validation, that is expected in strict mode.
Indexes never appear
Indexes are not created automatically on connect (unless deprecated syncIndexes: true).
npx mondel push --uri "$MONGODB_URI" --schema ./dist/schemas.js --dry-run
npx mondel push --uri "$MONGODB_URI" --schema ./dist/schemas.jsEnsure the schema module is compiled JS and exports schemas.
push cannot load TypeScript config
Install typescript in the project, or use mondel.config.js / .mjs.
Connection storms on serverless
Connecting and never reusing clients under huge concurrency can hit Atlas limits.
- Lower
maxPoolSize - Reuse factory; avoid opening many clients per request without need
- Prefer platform guidance for Lambda freeze/reuse
- Always use Atlas SRV connection strings
Soft delete documents still show up
Soft delete only sets deletedAt. Filter them out in queries:
await db.users.findMany({ deletedAt: { $exists: false } });Transactions fail on standalone MongoDB
Multi-document transactions need a replica set (Atlas provides this). Local single mongod without replSet will error.
ObjectId / BSON mismatch errors
Import ObjectId from mondel (or the same mongodb package version as the peer), not from a nested duplicate bson.
Geospatial queries return nothing
- Coordinates are
[longitude, latitude] - Index must be
2dsphere(runmondel push) - MongoDB 8 rejects malformed geo input
select fields missing at runtime but TS allows access
Projection is runtime-only; TypeScript does not narrow. Only use projected fields, or omit select.
