{"record":{"id":"cb46aab1e12c0b8f","repo":"remotion-dev/remotion","slug":"no-secret-was-provided-to-validatewebhooksignatu","errorCode":null,"errorMessage":"No 'secret' was provided to validateWebhookSignature().","messagePattern":"No 'secret' was provided to validateWebhookSignature\\(\\)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/lambda-client/src/validate-webhook-signature.ts","lineNumber":15,"sourceCode":"/*\n * @description Validates that the signature received by a webhook endpoint is authentic. If validation fails, an error is thrown.\n * @see [Documentation](https://remotion.dev/docs/lambda/validatewebhooksignature)\n */\nexport const validateWebhookSignature = ({\n\tsecret,\n\tbody,\n\tsignatureHeader,\n}: {\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')}`;","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/lambda-client/src/validate-webhook-signature.ts#L1-L33","documentation":"Thrown by validateWebhookSignature() in @remotion/lambda-client when the `secret` argument is falsy (empty string, null, undefined). The secret is the HMAC key used to verify that an incoming render-progress webhook genuinely came from your Lambda; without it, no signature can be trusted.","triggerScenarios":"Calling validateWebhookSignature({secret: '', ...}) or passing secret: undefined / null. The guard is a simple `if (!secret)` so any falsy value trips it.","commonSituations":"Reading the webhook secret from an env var that is not set in the current environment; passing the wrong key name; initializing the secret lazily and hitting the route before initialization completed.","solutions":["Ensure the webhook secret env var (e.g. REMOTION_WEBHOOK_SECRET) is set on every environment that handles webhooks, and pass it explicitly.","Fail fast at app boot if the secret is missing rather than per-request.","Confirm you are reading the same secret that was configured when deploying the Lambda function."],"exampleFix":"// before\nvalidateWebhookSignature({secret: process.env.WEBHOOK_SECRET, body, signatureHeader});\n\n// after\nconst secret = process.env.WEBHOOK_SECRET;\nif (!secret) throw new Error('WEBHOOK_SECRET not configured');\nvalidateWebhookSignature({secret, body, signatureHeader});","handlingStrategy":"validation","validationCode":"const secret = process.env.REMOTION_WEBHOOK_SECRET;\nif (!secret) throw new Error('REMOTION_WEBHOOK_SECRET is not set');\nvalidateWebhookSignature({secret, body, signatureHeader});","typeGuard":"const hasSecret = (s: unknown): s is string => typeof s === 'string' && s.length > 0;","tryCatchPattern":"try {\n  validateWebhookSignature({secret, body, signatureHeader});\n} catch (err) {\n  // Treat ANY validation failure as unauthenticated — do not leak which check failed.\n  return res.status(401).send('unauthorized');\n}","preventionTips":["Fail fast at boot if the webhook secret env var is missing.","Use the same secret value when calling renderMediaOnLambda and when validating.","Treat a missing-secret error as a 401, not a 500, to avoid leaking internals."],"tags":["lambda","webhook","security","validation"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}