I am getting an error
⨯ [TypeError: The "payload" argument must be of type object. Received null] {
code: 'ERR_INVALID_ARG_TYPE',
digest: '447529059'
}
when I have the following prisma server action (using next.js for context)
'use server'
import {PrismaClient} from '@prisma/client'
import {NewLesson} from "@/app/(portal)/admin/courses/[slug]/lessons/[lslug]/types/lesson";
import {revalidatePath} from 'next/cache'
const prisma = new PrismaClient()
const createOrUpdateLesson = async (data: NewLesson, cId: string, aId: string) => {
const {id, authorId, courseId, additionalResources, files, validations, ...rest} = data
try {
const course = await prisma.course.findFirstOrThrow({
where: {id: cId},
select: {slug: true}
})
const vConnectOrCreate = validations.map((v) => {
return {
where: {id: v.id},
create: {
value: v.value,
message: v.message,
type: v.type
}
}
})
const fConnectOrCreate = files.map((f) => {
return {
where: {id: f.id},
create: {
name: f.name,
type: f.type,
content: f.content
}
}
})
const rConnectOrCreate = additionalResources.map((a) => {
return {
where: {id: a.id},
create: {
type: a.type,
title: a.title,
value: a.value,
}
}
})
const lesson = await prisma.lesson.upsert({
where: {slug: data.slug},
update: {
...rest,
Author: {connect: {id: aId}},
Course: {connect: {id: cId}},
Validations: {
connectOrCreate: vConnectOrCreate
},
Files: {
connectOrCreate: fConnectOrCreate
},
AdditionalResources: {
connectOrCreate: rConnectOrCreate
}
},
create: {
...rest,
Author: {connect: {id: aId}},
Course: {connect: {id: cId}},
Validations: {
connectOrCreate: vConnectOrCreate
},
Files: {
connectOrCreate: fConnectOrCreate
},
AdditionalResources: {
connectOrCreate: rConnectOrCreate
}
},
include: {Validations: true, AdditionalResources: true, Files: true}
})
revalidatePath(`/courses/${course.slug}/lessons/${lesson.slug}`, 'page')
return {success: true, lesson}
} catch (error) {
console.error('Failed to create/update lesson:', error)
return {success: false, error: 'Failed to create/update course'}
}
}
export {createOrUpdateLesson}
I have the following schema
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
model Account {
id String @id @default(auto()) @map("_id") @db.ObjectId
userId String @db.ObjectId
user User @relation(fields: [userId], references: [id])
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
sesssion_state String?
}
model Session {
id String @id @default(auto()) @map("_id") @db.ObjectId
sessionToken String @unique
userId String @db.ObjectId
user User @relation(fields: [userId], references: [id])
expires DateTime
}
model VerificationToken {
id String @id @default(auto()) @map("_id") @db.ObjectId
identifier String
token String @unique
expires DateTime
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String?
login String @unique
email String @unique
password String @unique
emailVerified DateTime?
image String?
accounts Account[]
Articles Article[]
Comments Comment[]
Sessions Session[]
enrolledCourseIds String[] @db.ObjectId
membership Membership? @relation(fields: [membershipId], references: [id])
membershipId String? @db.ObjectId
roleId String? @db.ObjectId
role Role? @relation(fields: [roleId], references: [id])
BillingAddresses BillingAddress[]
AuthoredCourses Course[] @relation("Author")
EnrolledCourses Course[] @relation("Students", fields: [enrolledCourseIds], references: [id])
Lessons Lesson[]
Doc Doc[]
}
model Comment {
id String @id @default(auto()) @map("_id") @db.ObjectId
content String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
authorId String @db.ObjectId
author User @relation(fields: [authorId], references: [id])
articleId String @db.ObjectId
article Article @relation(fields: [articleId], references: [id])
}
model Article {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String @unique
slug String @unique
content String
image String?
description String?
comments Comment[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
authorId String @db.ObjectId
author User @relation(fields: [authorId], references: [id])
categoryId String @db.ObjectId
category Category @relation(fields: [categoryId], references: [id])
}
model Category {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String @unique
articles Article[]
courses Course[]
}
model Feature {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String @unique
MembershipTypes MembershipType[]
}
model MembershipType {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String @unique
price Int
duration Int
descrition String
featuresIds String[] @db.ObjectId
features Feature @relation(fields: [featuresIds], references: [id])
Memberships Membership[]
}
model Membership {
id String @id @default(auto()) @map("_id") @db.ObjectId
typeId String @db.ObjectId
type MembershipType @relation(fields: [typeId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Users User[]
}
model Role {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String @unique
users User[]
}
model BillingAddress {
id String @id @default(auto()) @map("_id") @db.ObjectId
line1 String
line2 String?
city String
state String?
postalCode String?
country String
email String @unique
userId String @db.ObjectId
user User @relation(fields: [userId], references: [id])
}
model Course {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String @unique
description String
slug String @unique
categoryId String? @db.ObjectId
category Category? @relation(fields: [categoryId], references: [id])
authorId String @db.ObjectId
studentIds String[] @db.ObjectId
Author User @relation(name: "Author", fields: [authorId], references: [id])
Students User[] @relation(name: "Students", fields: [studentIds], references: [id])
lessons Lesson[]
}
enum ValidationType {
ELEMENT_CONTAINS @map("Element Contains")
USED_FUNCTION @map("Used Function")
CREATED_ELEMENT @map("Created Element")
HAS_CODE_BLOCK @map("Has Code Block")
HAS_EXACT_CODE @map("Has Exact Code")
CREATED_COMMENT @map("Created Comment")
USED_VARIABLE @map("Used Variable")
USED_IMPORT @map("Used Import")
USED_HOOK @map("Used Hook")
IMPLEMENTED_INTERFACE @map("Implemented Interface")
EXTENDED_CLASS @map("Extended Class")
USED_STATE_MANAGEMENT @map("Used State Management")
IMPLEMENTED_EVENT_HANDLER @map("Implemented Event Handler")
}
enum AdditionalResourceType {
BLOG @map("blog")
DOC @map("doc")
EXTERNAL_LINK @map("external link")
}
model Validation {
id String @id @default(auto()) @map("_id") @db.ObjectId
lessonId String @db.ObjectId
Lesson Lesson @relation(fields: [lessonId], references: [id])
type ValidationType @default(ELEMENT_CONTAINS)
value String
message String?
}
model AdditionalResource {
id String @id @default(auto()) @map("_id") @db.ObjectId
type AdditionalResourceType
lessonId String @db.ObjectId
Lesson Lesson @relation(fields: [lessonId], references: [id])
title String @unique
value String
}
enum FileType {
JAVASCRIPT @map("js")
TYPESCRIPT @map("ts")
CSS @map("css")
HTML @map("html")
}
model File {
id String @id @default(auto()) @map("_id") @db.ObjectId
type FileType
name String
content String
lessonId String @db.ObjectId
Lesson Lesson @relation(fields: [lessonId], references: [id])
}
model Lesson {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
description String
step Int
slug String @unique
courseId String @db.ObjectId
Course Course @relation(fields: [courseId], references: [id])
authorId String @db.ObjectId
Author User @relation(fields: [authorId], references: [id])
duration Int
content String
Validations Validation[]
AdditionalResources AdditionalResource[]
Files File[]
}
model Doc {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String @unique
slug String @unique
description String
content String
authorId String @db.ObjectId
Author User @relation(fields: [authorId], references: [id])
}
I was expecting the system to save/update the lesson along with the needed resources and create the additional records or update them as needed.
I have been trying to use different upserts, for loops, and even trying to get it to tell me what data is invalid. My typescript is not seeing any issues with the data being passed either from the client component or in the script itself. I have been trying to do this so its as simple and easy to look at as possible.
Log error with console.log(error.stack) to show prisma error. console.log(error) don't show exact error message.
In my case ,It show connector error, Prisma load enviroment variables from .env.local when I retrieve or create. So I set database's env variables in .env.local too and resolved the error.