You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js+Prisma注册路由报错:payload必须为对象类型

Next.js注册路由报错:"payload"参数必须为对象,接收到null

错误日志

⨯ TypeError: The "payload" argument must be of type object. Received null
    at AsyncLocalStorage.exit (node:async_hooks:358:14)
    at POST (./src/app/api/sign-up/route.ts:244:17)
 ⨯ TypeError: The "payload" argument must be of type object. Received null
    at frame (node_modules\next\src\server\patch-error-inspect.ts:89:42)
    at getSourcemappedFrameIfPossible (node_modules\next\src\server\patch-error-inspect.ts:179:32)
    at parseAndSourceMap (node_modules\next\src\server\patch-error-inspect.ts:234:23)
    at exit (node_modules\next\src\server\patch-error-inspect.ts:224:32)
    at apply (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js:569:32)
    at apply (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js:593:32)
    at error (c:\Users\hp\OneDrive\Desktop\Mobile\bridge\src\app\api\sign-up\route.ts:256:16)
    at async AppRouteRouteModule.do (webpack://next/dist/src/server/route-modules/app-route/module.ts:529:14)
    at async AppRouteRouteModule.handle (webpack://next/dist/src/server/route-modules/app-route/module.ts:658:30)
    at async doRender (node_modules\next\src\server\base-server.ts:2504:29)
    at async responseGenerator (node_modules\next\src\server\base-server.ts:3027:21)
    at async DevServer.renderToResponseWithComponentsImpl (node_modules\next\src\server\base-server.ts:3039:23)
    at async DevServer.renderPageComponent (node_modules\next\src\server\base-server.ts:3597:15)
    at async DevServer.renderToResponseImpl (node_modules\next\src\server\base-server.ts:3659:23)
    at async DevServer.pipeImpl (node_modules\next\src\server\base-server.ts:1698:20)
    at async NextNodeServer.handleCatchallRenderRequest (node_modules\next\src\server\next-server.ts:1034:6)
    at async DevServer.handleRequestImpl (node_modules\next\src\server\base-server.ts:1462:8)
    at async (node_modules\next\src\server\dev\next-dev-server.ts:514:13)
    at async Span.traceAsyncFn (node_modules\next\src\trace\trace.ts:143:13)
    at async DevServer.handleRequest (node_modules\next\src\server\dev\next-dev-server.ts:512:19)
    at async invokeRender (node_modules\next\src\server\lib\router-server.ts:284:10)
    at async handleRequest (node_modules\next\src\server\lib\router-server.ts:530:15)
    at async requestHandlerImpl (node_modules\next\src\server\lib\router-server.ts:576:6)
    at async Server.requestListener (node_modules\next\src\server\lib\start-server.ts:146:6)
  254 |         );
  255 |     } catch (error) {
> 256 |         console.error('Error during registration:', error);
      |                ^
  257 |
  258 |         return new Response(
  259 |             JSON.stringify({ {
  code: 'ERR_INVALID_ARG_TYPE'
}
 POST /api/sign-up 500 in 3844ms

问题背景

我在Next.js中开发了一个接收用户名、邮箱、密码的注册接口,使用Prisma操作数据库,要求用户创建后立即发送验证邮件。但运行时持续触发上述错误,测试多种请求payload仍无法解决,怀疑是Prisma相关问题。

相关代码

注册路由代码(src/app/api/sign-up/route.ts)

import bcrypt from 'bcryptjs';
import { PrismaClient } from '@prisma/client';
import { sendVerificationEmail } from '@/helpers/sendVerificationEmail';

const prisma = new PrismaClient();

export async function POST(request: Request) {
    try {
       
        const  { username, email, password } = await request.json();
       

        if (!username || !email || !password) {
            console.log('Missing required fields:', { username, email, password });
            return new Response(
                JSON.stringify({
                    success: false,
                    message: 'Username, email, and password are required.',
                }),
                { status: 400 }
            );
        }

        const existingUserByUsername = await prisma.user.findFirst({
            where: {
                AND: [{ username }, { isVerified: true }],
            },
        });

        if (existingUserByUsername) {
            console.log('Username already taken:', username);
            return new Response(
                JSON.stringify({
                    success: false,
                    message: 'Username is already taken.',
                }),
                { status: 400 }
            );
        }

  
        const existingUserByEmail = await prisma.user.findUnique({
            where: { email },
        });

        const verifyCode = Math.floor(10000 + Math.random() * 900000).toString();
        const hashedPassword = await bcrypt.hash(password, 10);

        if (existingUserByEmail) {
            if (existingUserByEmail.isVerified) {
                console.log('Email already verified:', email);
                return new Response(
                    JSON.stringify({
                        success: false,
                        message: 'User already exists with this email.',
                    }),
                    { status: 400 }
                );
            }

            console.log('Updating unverified user:', email);
            const verifyCodeExpiry = new Date(Date.now() + 3600000);

            await prisma.user.update({
                where: { email },
                data: {
                    password: hashedPassword,
                    verifyCode,
                    verifyCodeExpiry,
                },
            });
        } else {
           
            console.log('Creating new user:', { username, email });
            const verifyCodeExpiry = new Date(Date.now() + 3600000);

            await prisma.user.create({
                data: {
                    username,
                    email,
                    password: hashedPassword,
                    verifyCode,
                    verifyCodeExpiry,
                    isVerified: false,
                    isAcceptingMessage: true,
                    messages: {
                        create: [],
                    },
                },
            });
        }

        const emailResponse = await sendVerificationEmail(email, username, verifyCode);
        console.log('Email response:', emailResponse);

        if (!emailResponse || !emailResponse.success) {
            console.log('Failed to send verification email:', emailResponse);
            return new Response(
                JSON.stringify({
                    success: false,
                    message: emailResponse?.message || 'Failed to send verification email.',
                }),
                { status: 500 }
            );
        }

        return new Response(
            JSON.stringify({
                success: true,
                message: 'User registered successfully. Please verify your email.',
            }),
            { status: 200 }
        );
    } catch (error) {
        console.error('Error during registration:', error);

        return new Response(
            JSON.stringify({
                success: false,
                message: 'Error registering user',
            }),
            { status: 500 }
        );
    }
}

Prisma模型(prisma/schema.prisma)

model Message{
    id        Int      @id @default(autoincrement())
    userId  Int 
    user User @relation(fields:[userId],references:[id])
    content String
    createdAt DateTime @default(now())
}

model User{
  id Int @id @default(autoincrement())
  username String @unique 
  email String @unique 
  password String 
  verifyCode String
  verifyCodeExpiry DateTime
  isVerified Boolean @default(false)
  isAcceptingMessage Boolean
  messages Message[]
}

解决方案

1. 修复JSON解析错误处理

请求body无效或非JSON格式会导致request.json()返回null,在代码中添加JSON解析的错误捕获:

// 替换原有的request.json()部分
let body;
try {
  body = await request.json();
} catch (e) {
  return new Response(
    JSON.stringify({ 
      success: false, 
      message: '请求格式错误,请传递有效的JSON' 
    }),
    { status: 400, headers: { 'Content-Type': 'application/json' } }
  );
}
const { username, email, password } = body;

2. 优化PrismaClient实例化(避免重复创建)

在src/lib/prisma.ts中创建单例PrismaClient:

import { PrismaClient } from '@prisma/client';

const prisma = global.prisma || new PrismaClient({
  log: ['query', 'info', 'warn', 'error'], // 可选,便于调试数据库操作
});

if (process.env.NODE_ENV !== 'production') global.prisma = prisma;

export default prisma;

然后在注册路由中替换导入:

// 替换原有的import { PrismaClient } from '@prisma/client';和const prisma = new PrismaClient();
import prisma from '@/lib/prisma';

3. 移除不必要的关联创建代码

创建用户时无需显式创建空的messages数组,Prisma会自动处理关联字段:

// 修改prisma.user.create的data部分,删除messages字段
await prisma.user.create({
    data: {
        username,
        email,
        password: hashedPassword,
        verifyCode,
        verifyCodeExpiry,
        isVerified: false,
        isAcceptingMessage: true,
        // 移除下面这行
        // messages: { create: [] },
    },
});

4. 检查验证邮件发送函数

确认sendVerificationEmail内部没有传递null作为需要对象类型的参数,比如邮件服务的请求payload必须是有效对象。例如如果使用Nodemailer,确保mailOptions的所有字段(如to、subject、html)都不为null。

5. 修复语法错误(错误日志中暴露的问题)

错误日志显示JSON.stringify({ { code: 'ERR_INVALID_ARG_TYPE' } })存在语法错误,确保所有JSON.stringify的参数都是合法对象(避免嵌套大括号)。

内容的提问来源于stack exchange,提问作者Ravi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:13:11