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

Next.js API路由报错:无法将Symbol值转换为字符串求助

Next.js API路由出现"Cannot convert a Symbol value to a string" TypeError问题求助

在Next.js的API路由目录中遇到TypeError错误,反复收到提示:Cannot convert a Symbol value to a string,但代码中并未显式使用Symbol类型,也没有手动的字符串转换操作。以下是相关代码及错误信息,求排查思路:

API路由代码(/api/email/meetingNotification)

import { NextResponse } from 'next/server';
import MeetingNotification from "../../../../../emails/meetingNotification";
import { resend } from '@/utils/resend';

interface EmailData {
    schoolName: string;
    email: string;
    clubName: string;
    meetingDate: string;
    meetingTime: string;
    meetingDescription: string;
    meetingName: string;
    location: string;
    type: string;
    mandatory: boolean;
    meetingId: string;
    clubCode: string;
}

export async function POST(request: Request) {
    const emails: EmailData[] = await request.json();

    try {
        const emailPromises = emails.map(({
         schoolName,
         email,
         clubName,
         meetingDate,
         meetingTime,
         meetingDescription,
         meetingName,
         location,
         type,
         mandatory,
         meetingId,
         clubCode
         }: EmailData) => {
            return resend.emails.send({
                from: `${clubName} <${clubCode}@clubcentric.org>`,
                to: email,
                subject: `A new meeting has been scheduled for ${clubName}`,
                react: MeetingNotification({
                    schoolName,
                    location,
                    type,
                    clubName,
                    meetingDate: new Date(meetingDate).toDateString(),
                    meetingId,
                    meetingTime,
                    meetingDescription,
                    meetingName,
                    mandatory,
                })
            });
        });

        await Promise.all(emailPromises);

        return NextResponse.json({ status: 'Ok' }, { status: 200 });
    } catch (e: unknown) {
        console.error('Failed to send emails:', e);
        return NextResponse.json(
            { error: 'Internal server error. Please try resending the emails.' },
            { status: 500 }
        );
    }
}

sendMeetingNotification()函数代码

if (meetingData.meeting_data.push_notification) {
    const { data: membershipsData, error: membershipsError } = await supabase
        .from('memberships')
        .select('user_id')
        .eq('club_id', userId);

    if (membershipsError) {
        console.error('Error fetching memberships:', membershipsError.message);
        toast.error("There was an error: Memberships Unavailable")
        return;
    }

    const emails = [];

    for (const member of membershipsData) {
        const { data: userDirectoryData, error: userDirectoryError } = await supabase
            .from('user_directory')
            .select('email')
            .eq('user_id', member.user_id);

        if (userDirectoryError) {
            console.error('Error fetching user directory:', userDirectoryError.message);
            toast.error("There was an error: User Directory Unavailable")
            continue;
        }

        for (const members of userDirectoryData) {
            emails.push({
                schoolName: clubSchool,
                email: members.email,
                clubName: clubName,
                meetingDate: selectedDate?.toISOString(), 
                meetingTime: `${startTime} - ${endTime}`,
                meetingDescription: meetingData.meeting_data.description,
                meetingName: meetingData.meeting_data.title,
                mandatory: meetingData.meeting_data.mandatory,
                clubCode: clubCode,
                location: meetingData.meeting_data.location,
                type: selectedType,
                meetingId: meetingData.meeting_id,
            });
        }
    }

    // Send POST request to the endpoint
    const response = await fetch('/api/email/meetingNotification', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(emails),
    });

    if (!response.ok) {
        console.error('Failed to send emails:');
        toast.error("Notification System Error!")
    } else {
        console.log('Emails sent successfully');
        router.push("/dashboard/club/meetings")
    }
} else {
    console.log('Push notifications are disabled: Emails not sent!');
}

错误信息

Failed to send emails: TypeError: Cannot convert a Symbol value to a string
    at _ (/Users/musamalik/Downloads/[redacted]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:254562)
    at Object.get (/Users/musamalik/Downloads/[redacted]/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:254683)
    at Proxy.toString (<anonymous>)
    at MeetingNotification (webpack-internal:///(rsc)/./emails/meetingNotification.tsx:319:93)
    at eval (webpack-internal:///(rsc)/./src/app/api/email/meetingNotification/route.ts:19:95)
    at Array.map (<anonymous>)
    at POST (webpack-internal:///(rsc)/./src/app/api/email/meetingNotification/route.ts:14:38)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /Users/musamalik/Downloads/[redacted]/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:63251

排查思路与解决方案

从错误栈可以明确,问题出在MeetingNotification.tsx文件的第319行,该位置在执行字符串转换时遇到了Symbol类型的值。虽然你的API和调用代码中没有显式使用Symbol,但可能存在以下隐式场景:

1. 检查邮件组件的关键代码

直接查看MeetingNotification.tsx第319行的代码,确认此处是否在做字符串拼接、模板字符串渲染,或者将props值转换为字符串的操作。重点检查该位置用到的所有props变量(比如type、location、mandatory等),是否有变量被意外赋值为Symbol类型。

2. 对传入组件的props做安全转换

在API路由调用MeetingNotification前,强制将所有props转换为预期类型,避免Symbol或其他异常类型传入:

// 在map循环内,调用MeetingNotification前添加
const safeProps = {
  schoolName: String(schoolName),
  location: String(location),
  type: String(type),
  clubName: String(clubName),
  meetingDate: new Date(meetingDate).toDateString(),
  meetingId: String(meetingId),
  meetingTime: String(meetingTime),
  meetingDescription: String(meetingDescription),
  meetingName: String(meetingName),
  mandatory: Boolean(mandatory),
};

// 用转换后的props调用组件
react: MeetingNotification(safeProps)

3. 校验前端传入的参数类型

检查sendMeetingNotification函数中构造emails数组时的变量(比如selectedType、clubSchool、startTime等),确认这些变量是否为字符串类型。如果某些变量来自第三方库或状态管理,可能被意外设置为Symbol。可以在构造数组时添加类型日志:

// 在emails.push前添加
console.log("Email item types:", {
  schoolName: typeof clubSchool,
  type: typeof selectedType,
  location: typeof meetingData.meeting_data.location
});

4. 组件内部添加类型防护

在MeetingNotification组件中,对接收的props做类型断言或默认值处理,确保所有用到的变量都是可安全转换为字符串的类型:

interface MeetingNotificationProps {
  schoolName: string;
  location: string;
  type: string;
  // ...其他属性
}

export default function MeetingNotification(props: MeetingNotificationProps) {
  // 给所有props设置默认值,避免undefined或异常类型
  const {
    schoolName = "",
    location = "",
    type = "",
    // ...其他属性
  } = props;

  // 组件渲染代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:05:54