{"record":{"id":"d7f5fe4dc6df5715","repo":"remotion-dev/remotion","slug":"validatewebhooksignature-can-only-be-called-from-n","errorCode":null,"errorMessage":"validateWebhookSignature can only be called from Node.JS","messagePattern":"validateWebhookSignature can only be called from Node\\.JS","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lambda-client/src/validate-webhook-signature.ts","lineNumber":27,"sourceCode":"}: {\n\tsecret: string;\n\tbody: unknown;\n\tsignatureHeader: string;\n}) => {\n\tif (!secret) {\n\t\tthrow new TypeError(\n\t\t\t\"No 'secret' was provided to validateWebhookSignature().\",\n\t\t);\n\t}\n\n\tif (!body) {\n\t\tthrow new TypeError(\n\t\t\t\"No 'body' was provided to validateWebhookSignature().\",\n\t\t);\n\t}\n\n\tif (typeof require === 'undefined') {\n\t\tthrow new Error('validateWebhookSignature can only be called from Node.JS');\n\t}\n\n\tconst Crypto = require('crypto');\n\n\tconst hmac = Crypto.createHmac('sha512', secret);\n\tconst signature = `sha512=${hmac.update(JSON.stringify(body)).digest('hex')}`;\n\n\tif (!signatureHeader || signatureHeader === 'NO_SECRET_PROVIDED') {\n\t\tthrow new Error('No webhook signature was provided');\n\t}\n\n\tif (signatureHeader !== signature) {\n\t\tthrow new Error('Signatures do not match');\n\t}\n};\n","sourceCodeStart":9,"sourceCodeEnd":43,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/lambda-client/src/validate-webhook-signature.ts#L9-L43","documentation":"Thrown by validateWebhookSignature() when `require` is undefined at runtime, i.e. the function is being called outside Node.js. The implementation uses CommonJS `require('crypto')` to compute the HMAC, which only exists in Node and not in browser/edge bundlers.","triggerScenarios":"Calling validateWebhookSignature() from code bundled for the browser (Webpack browser target, Vite client build), a Cloudflare Worker, a Vercel Edge Function, or any environment that shims away `require`.","commonSituations":"Importing @remotion/lambda-client in a Next.js client component or in a route handler running on the edge runtime; bundling server code with a browser target by mistake.","solutions":["Only call validateWebhookSignature() from a Node.js runtime (Node Lambda, Express server, Next.js Node route).","In Next.js, mark the importing module with 'use server' or ensure the route runs on the Node.js runtime, not the Edge runtime.","If you must verify webhooks in the browser, do not use this function — verify server-side and trust your own backend."],"exampleFix":"// before (Next.js edge route)\nexport const runtime = 'edge';\nexport async function POST(req) {\n  await validateWebhookSignature({secret, body: await req.json(), signatureHeader: req.headers.get('X-Remotion-Signature')});\n}\n\n// after\nexport const runtime = 'nodejs';\nexport async function POST(req) {\n  await validateWebhookSignature({secret, body: await req.json(), signatureHeader: req.headers.get('X-Remotion-Signature')});\n}","handlingStrategy":"try-catch","validationCode":"// Ensure the route runs on Node.js — e.g. Next.js:\n// export const runtime = 'nodejs';\n// Then the call is safe.","typeGuard":"const isNode = (): boolean => typeof process !== 'undefined' && typeof process.versions?.node === 'string' && typeof require !== 'undefined';","tryCatchPattern":"if (typeof require === 'undefined') {\n  return res.status(500).send('webhook validation must run in Node.js runtime');\n}\nvalidateWebhookSignature({secret, body, signatureHeader});","preventionTips":["Pin webhook routes to the Node.js runtime in your framework config.","Do not import @remotion/lambda-client into client bundles.","If using Next.js, set `export const runtime = 'nodejs'` on the route."],"tags":["lambda","webhook","node-js","runtime","bundler"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}