Node deprecated code and solutions for 2024

This is an update on as much of the changes i had to make to mosh’s course (that I can remember) the course is still good and i can confirm with my deployment. Much of this is discussed in other form posts however much of it I found had also changed as well so i’m just gonna say what worked for me as of April 2024.


Joi Error is objectID is not a function,
solution remove id and replace with .string.hex.length.required
Error joi schema is deprecated
Solution const schema = joi.object also return as shown below there is no

function validateMovie(movie) {
const schema = Joi.object ({
title: Joi.string().min(5).max(50).required(),
genreId: Joi.string().hex().length(24).required(),
numberInStock: Joi.number().min(1).required(),
dailyRentalRate: Joi.number().min(1).required()

 return schema.validate(movie); 

Joi.validate no longer a function
Solution schema.validate

const result = schema.validate(req.body);
if (result.error) {
res.status(400).send('Validation failed: ’ + result.error.details[0].message)

winston Error, with transports, mongoDB(need to pass DB string, this breaks on deployment as you need to pass the environment variable instead of localhost, i remove on deployment pending refactor), and console not logging, (basically everything lol)

solution: fyi this is refactored code for deployment not in index.js

database query logic he says to call Movie.update or remove
solution, if it’s one you must do movie.updateOne or many it’s movie.updateMany, also delete same thing but it’s deleteMany or deleteOne,
also use findByIdAndUpdate and findByIdAndDelete (don’t remember what he uses)

Mongoose Types mosh might have you make a id or auth token like this customerId = mongoose.Types.ObjectId();
Solution: add new in front
customerId = new mongoose.Types.ObjectId();

fawn idk this one id broken as heck no updates in 6 years, i just kept the first solution he showed

I think that’s it as far as i remember please comment if you find anything i missed.

Same for me as well, First Solution is working find, but when try with fawn it throws an error

Unhandled rejection MongoError: Unsupported OP_QUERY command: insert. The client driver may require an upgrade. For more details see


@theorion I have a question. What happens to the first line of the validation.js where const Joi = require('joi)? Is it changing in any way?
For some reason, I’m getting this error
TypeError: schema.validate is not a function
And I can’t seem to figure out why

For some context, I’m getting this error after I tried to send an authentication post request using postman

So the import doesn’t change, but the first line and return statement need to be changed in the validate function if your using the most recent version of Joi. My guess is maybe you didn’t change the first line. feel free to show your code if your still having problems.

the validatemodel block should be like this:

function validateMovie(movie) {
const schema = Joi.object({
title: Joi.string().required()
return schema.validate(movie)

@theorion By validatemodel block, are you referring to validate.js or listings.js from the backend?.. Those are the only files that I think required some edits for the joi package to work.
Here is my code:
const Joi = require(“joi”);

module.exports = schema => (req, res, next) => {
const result = schema.validate(
? { …req.body, location: JSON.parse(req.body.location) }
: req.body

if (result.error)
return res.status(400).send({ error: result.error.details[0].message });


const express = require(“express”);
const router = express.Router();
const Joi = require(“joi”);
const multer = require(“multer”);

const store = require(“…/store/listings”);
const categoriesStore = require(“…/store/categories”);
const validateWith = require(“…/middleware/validation”);
const auth = require(“…/middleware/auth”);
const imageResize = require(“…/middleware/imageResize”);
const delay = require(“…/middleware/delay”);
const listingMapper = require(“…/mappers/listings”);
const config = require(“config”);

const upload = multer({
dest: “uploads/”,
limits: { fieldSize: 25 * 1024 * 1024 },

const schema = Joi.object({
title: Joi.string().required(),
description: Joi.string().allow(“”),
price: Joi.number().required().min(1),
categoryId: Joi.number().required().min(1),
location: Joi.object({
latitude: Joi.number().required(),
longitude: Joi.number().required(),

const validateCategoryId = (req, res, next) => {
if (!categoriesStore.getCategory(parseInt(req.body.categoryId)))
return res.status(400).send({ error: “Invalid categoryId.” });


router.get(“/”, (req, res) => {
const listings = store.getListings();
const resources =;
// Order of these middleware matters.
// “upload” should come before other “validate” because we have to handle
// multi-part form data. Once the upload middleware from multer applied,
// request.body will be populated and we can validate it. This means
// if the request is invalid, we’ll end up with one or more image files
// stored in the uploads folder. We’ll need to clean up this folder
// using a separate process.
// auth,
upload.array(“images”, config.get(“maxImageCount”)),

async (req, res) => {
const listing = {
title: req.body.title,
price: parseFloat(req.body.price),
categoryId: parseInt(req.body.categoryId),
description: req.body.description,
listing.images = => ({ fileName: fileName }));
if (req.body.location) listing.location = JSON.parse(req.body.location);
if (req.user) listing.userId = req.user.userId;




module.exports = router;

Hope this provides more context

I’m referring to the modules folders that contain files where interfaces are defined for users, customers, movies, genres. That is the first use case for Joi and i assumed that’s where he encountered the problem. But thanks for the clarification on other modules I had trouble remembering every module where joi was used.