Next.js v13+ API路由部署AWS Amplify时触发解构错误求助
错误信息
TypeError: Cannot destructure property 'environmentVariableSelector' of 'undefined' as it is undefined.
at d (.next/server/chunks/5936.js:15:31351)
at eg (.next/server/chunks/5936.js:9:5315)
at new ex (.next/server/chunks/5936.js:9:6739)
at 11151 (.next/server/app/api/stripe/webhook/route.js:1:4571)
相关代码
Stripe Webhook路由代码(app/api/stripe/webhook/route.js)
import { NextResponse } from "next/server"; import Stripe from "stripe"; import { updateUserGroupStripe } from "@/lib/actions/admin.action"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); export async function POST(req) { try { const text = await req.text(); const sig = req.headers.get("stripe-signature"); const event = stripe.webhooks.constructEvent( text, sig, process.env.STRIPE_WEBHOOK_SECRET ); await updateUserGroupStripe(payload); return NextResponse.json({ received: true }); } catch (err) { console.error(`❌ Error:`, err.message); return NextResponse.json({ error: err.message }, { status: 400 }); } }
服务端Cognito交互函数(@/lib/actions/admin.action.js)
"use server"; import { CognitoIdentityProviderClient, AdminAddUserToGroupCommand, AdminRemoveUserFromGroupCommand, AdminUpdateUserAttributesCommand, } from "@aws-sdk/client-cognito-identity-provider"; const client = new CognitoIdentityProviderClient({ region: process.env.COGNITO_REGION, credentials: { accessKeyId: process.env.COGNITO_ACCESS_KEY_ID, secretAccessKey: process.env.COGNITO_ACCESS_SECRET, }, }); export async function updateUserGroup({ username, subscription_id, subscription_plan_id, subscription_next_billing_time, action, }) { // 逻辑省略 const updateAttributesCommand = new AdminUpdateUserAttributesCommand({ UserPoolId: userPoolId, Username: username, UserAttributes: attributesToUpdate, }); await client.send(updateAttributesCommand); } export async function updateUserGroupStripe({ username, subscription_id, subscription_plan_id, subscription_next_billing_time, customer_id, action, group, }) { // 逻辑省略 const updateAttributesCommand = new AdminUpdateUserAttributesCommand({ UserPoolId: userPoolId, Username: username, UserAttributes: attributesToUpdate, }); await client.send(updateAttributesCommand); }
已确认事项
- Amplify控制台中所有环境变量均已配置
- 代码在本地环境运行正常
- 已更新AWS相关依赖库
排查与解决步骤
调整Cognito客户端初始化时机
不要在模块顶层初始化CognitoIdentityProviderClient,改为在函数内部初始化。Amplify服务端运行时可能在模块加载阶段无法读取环境变量,导致客户端初始化失败:"use server"; import { CognitoIdentityProviderClient, AdminAddUserToGroupCommand, AdminRemoveUserFromGroupCommand, AdminUpdateUserAttributesCommand, } from "@aws-sdk/client-cognito-identity-provider"; export async function updateUserGroupStripe({ /* 参数 */ }) { // 函数内部初始化客户端 const client = new CognitoIdentityProviderClient({ region: process.env.COGNITO_REGION, credentials: { accessKeyId: process.env.COGNITO_ACCESS_KEY_ID, secretAccessKey: process.env.COGNITO_ACCESS_SECRET, }, }); // 后续业务逻辑... }修复Stripe Webhook中的未定义变量
原代码中直接使用未定义的payload变量,需从Stripe事件中提取:const event = stripe.webhooks.constructEvent( text, sig, process.env.STRIPE_WEBHOOK_SECRET ); // 从event中提取payload const payload = event.data.object; await updateUserGroupStripe(payload);验证Amplify环境变量配置
确保Amplify中配置的环境变量在构建阶段可被Next.js读取。对于服务端变量,无需前缀,但要确认Amplify的构建流程没有屏蔽这些变量,必要时在amplify.yml中显式导出环境变量:build: commands: - export STRIPE_SECRET_KEY=$STRIPE_SECRET_KEY - export STRIPE_WEBHOOK_SECRET=$STRIPE_WEBHOOK_SECRET - npm run build检查Amplify的Next.js构建配置
确认amplify.yml中启用了App Router支持,构建命令和产物目录配置正确:frontend: phases: preBuild: commands: - npm install build: commands: - npm run build artifacts: baseDirectory: .next files: - '**/*' cache: paths: - node_modules/**/*查看Amplify构建日志细节
进入Amplify控制台的构建日志,检查构建阶段是否有环境变量加载失败、模块打包警告等信息,通过日志定位具体依赖或配置问题。
内容的提问来源于stack exchange,提问作者Damiano Dotto

