{"record":{"id":"810d62d4077f026e","repo":"remotion-dev/remotion","slug":"err-message","errorCode":null,"errorMessage":"${err.message}","messagePattern":"\\$\\{err\\.message\\}","errorType":"http","errorClass":null,"httpStatus":500,"severity":"warning","filePath":"packages/lambda-client/src/express-webhook.ts","lineNumber":53,"sourceCode":"\t\t\t\tsignatureHeader: req.header('X-Remotion-Signature') as string,\n\t\t\t\tbody: req.body,\n\t\t\t\tsecret,\n\t\t\t});\n\n\t\t\t//  custom logic\n\t\t\tconst payload = req.body;\n\t\t\tif (payload.type === 'success' && onSuccess) {\n\t\t\t\tawait onSuccess(payload);\n\t\t\t} else if (payload.type === 'error' && onError) {\n\t\t\t\tawait onError(payload);\n\t\t\t} else if (payload.type === 'timeout' && onTimeout) {\n\t\t\t\tawait onTimeout(payload);\n\t\t\t}\n\n\t\t\t// send response\n\t\t\tres.status(200).json({success: true});\n\t\t} catch (err) {\n\t\t\tres.status(500).json({\n\t\t\t\tsuccess: false,\n\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t});\n\t\t}\n\t};\n}\n","sourceCodeStart":35,"sourceCodeEnd":60,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/lambda-client/src/express-webhook.ts#L35-L60","documentation":"This is not a thrown exception to the caller — it is the express webhook middleware's catch-all. Any error raised during webhook signature validation or inside the onSuccess/onError/onTimeout callbacks is caught and returned as HTTP 500 with body {success:false, error:message}. The error surface that callers (the Remotion backend POSTing the webhook) see is a 500 response.","triggerScenarios":"The webhook endpoint receives a request whose X-Remotion-Signature does not validate (wrong secret), or one of the user-supplied callbacks throws.","commonSituations":"Webhook secret in renderMediaOnLambda differs from the one configured in expressWebhook; onSuccess writes to a DB that is down; callback throws on an unexpected payload shape.","solutions":["Ensure the webhook secret passed to renderMediaOnLambda matches the secret in expressWebhook options","Make onSuccess/onError/onTimeout resilient — never let them throw (wrap their internals in try/catch and still return 200)","Inspect the 500 response body's error field to identify the failing callback or signature mismatch"],"exampleFix":"// before - callback can throw\nexpressWebhook({ secret, onSuccess: async (p) => { await db.insert(p); } });\n\n// after - swallow callback errors so webhook stays reliable\nexpressWebhook({\n  secret,\n  onSuccess: async (p) => {\n    try { await db.insert(p); } catch (e) { console.error('cb failed', e); }\n  },\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// The middleware already catches; make callbacks resilient so it stays 200\nexpressWebhook({\n  secret,\n  onSuccess: async (p) => { try { await handleSuccess(p); } catch (e) { console.error(e); } },\n});","preventionTips":["Keep the webhook secret identical on both render and server sides","Never throw inside onSuccess/onError/onTimeout — swallow and log","Return 200 even on callback errors so the backend does not retry aggressively"],"tags":["webhook","http","express","signature"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}