NextJS+Prisma+MongoDB创建Post时提示缺失title但参数存在
创建Post时Prisma提示缺失title参数但参数实际存在
问题描述
使用NextJS、Prisma和MongoDB构建应用,发送POST请求创建Post时失败,日志明确提示Argument title is missing,但前后端日志均确认title参数已存在于请求体中。
错误信息
Error during the post creation PrismaClientValidationError: Invalid `prisma.post.create()` invocation: { data: { title: "this is a new post", // 此处title明明存在 desc: "this new post has many tags #cooking #testing #evening #life ##coding", img: "", slug: "this-is-a-new-post", userEmail: "testemail@test.com", postTags: { create: [ { tag: { connect: { slug: "cooking" } } }, { tag: { create: { slug: "pastry" } } }, { tag: { create: { slug: "evening" } } }, { tag: { connect: { slug: "life" } } }, { tag: { connect: { slug: "coding" } } } ] } } } Argument `title` is missing. // 但错误提示title缺失 at Zn (C:\Users\USER\Desktop\freeCodeCamp\reactCourse\next-blog\node_modules\@prisma\client\runtime\library.js:117:5888) at ni.handleRequestError (C:\Users\USER\Desktop\freeCodeCamp\reactCourse\next-blog\node_modules\@prisma\client\runtime\library.js:124:6516) at ni.handleAndLogRequestError (C:\Users\USER\Desktop\freeCodeCamp\reactCourse\next-blog\node_modules\@prisma\client\runtime\library.js:124:6206) at ni.request (C:\Users\USER\Desktop\freeCodeCamp\reactCourse\next-blog\node_modules\@prisma\client\runtime\library.js:124:5926) at async l (C:\Users\USER\Desktop\freeCodeCamp\reactCourse\next-blog\node_modules\@prisma\client\runtime\library.js:129:10023) at async POST (webpack-internal:///(rsc)/./src/app/api/posts/route.js:80:29) at async C:\Users\USER\Desktop\freeCodeCamp\reactCourse\next-blog\node_modules\next\dist\compiled\next-server\app-route.runtime.dev.js:6:62609 { clientVersion: '5.6.0' }
前端代码
const postTread = async () => { console.log('Request Payload:', { title: title, desc: desc, img: imageURL, slug: slugify(title), postTags: tagify(desc) }); // 此处可以正常打印包含title的请求体 const res = await fetch('http://localhost:3000/api/posts', { method: 'POST', body: JSON.stringify({ title: title, desc: desc, img: imageURL, slug: slugify(title), postTags: tagify(desc) }), }); if (!res.ok) { throw new Error('Failed to post'); } // 请求成功则刷新页面 const data = await res.json(); if (data) { router.refresh(); } };
后端代码
export const POST = async (req) => { const session = await getAuthSession(); if (!session) { return new NextResponse( JSON.stringify({ message: 'Not Authenticated!' }, { status: 401 }) ) }; try { const body = await req.json(); console.log('Body: ', body) // 此处可以正常打印包含title的请求体 const createdPost = await prisma.post.create({ data: { ...body, userEmail: session.user.email, postTags: { create: await Promise.all(body.postTags.map( async(tag) => { // 跳过重复标签 const existingTag = await prisma.tag.findUnique({ where: { slug: tag } }) if (existingTag) { return { tag: { connect: { slug: tag }}} } else { return { tag: { create: { slug: tag }}} } }) } }} }); console.log("Created Post: ", createdPost) // 该行日志未打印,说明创建失败 return new NextResponse(JSON.stringify(createdPost, { status: 200 })); } catch (error) { console.error('Error during the post creation', error); return new NextResponse( JSON.stringify({ message: 'Failed to POST' }, { status: 500 }) ); } };
Prisma Schema
generator client { provider = "prisma-client-js" } datasource db { provider = "mongodb" url = env("DATABASE_URL") } model Tag { id String @id @default(cuid()) @map("_id") slug String @unique title String img String? posts PostTag[] } model PostTag { id String @id @default(cuid()) @map("_id") postSlug String tagSlug String post Post @relation(fields: [postSlug], references: [slug]) tag Tag @relation(fields: [tagSlug], references: [slug]) @@unique([postSlug, tagSlug]) } model Post { id String @id @default(cuid()) @map("_id") createdAt DateTime @default(now()) slug String @unique title String // Post的title字段 desc String img String? views Int @default(0) postTags PostTag[] userEmail String user User @relation(fields: [userEmail], references: [email]) comments Comment[] } // 其余Schema(用户、会话等)
已尝试的排查步骤
- 改为显式传递title等参数,问题依旧;
- 清空数据库集合(保留用户和会话数据);
- 执行
npx prisma generate、npx prisma db push、npx prisma validate均通过; - 重复测试仍出现相同错误。
期望结果
prisma.post.create()能正常执行,根据请求体中的参数创建Post记录。
开发环境
- 系统:Windows
- 数据库:MongoDB
- Node.js版本:v18.17.1
- Prisma版本:v5.6.0
解决方案
问题出在Tag模型的必填字段title。在创建新Tag时,你只传递了slug,但Prisma要求Tag的title是必填项(Schema中title String未加?)。虽然错误提示指向Post的title缺失,但这是Prisma的错误提示误导——实际是嵌套创建Tag时缺少了必填的title字段。
修改后端代码中创建Tag的逻辑,为新Tag添加title值(可以直接用slug作为title,或者做格式化处理):
postTags: { create: await Promise.all(body.postTags.map(async(tag) => { const existingTag = await prisma.tag.findUnique({ where: { slug: tag } }) if (existingTag) { return { tag: { connect: { slug: tag }}} } else { // 添加title字段,这里用slug转成首字母大写的格式作为示例 const tagTitle = tag.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); return { tag: { create: { slug: tag, title: tagTitle }}} } }) }
同时,检查前端的tagify函数生成的tag格式是否符合预期,确保每个tag是有效的slug字符串。
最后,重新执行npx prisma generate确保客户端代码更新,再测试创建Post的接口即可解决问题。
内容的提问来源于stack exchange,提问作者JavierS
相关产品推荐
相关产品推荐

