remotion-dev/remotion · error
${err instanceof Error ? err.message : String(err)}
Error message
${err instanceof Error ? err.message : String(err)} What it means
Generic error surfaced by the Next.js pages-router webhook handler when one of the onSuccess/onTimeout/onError callbacks throws. The thrown value is normalized to a string (Error.message if it is an Error, else String(err)) and returned as a JSON 500 response so the caller sees what failed inside the callback.
Source
Thrown at packages/lambda-client/src/pages-router-webhook.ts:62
body: req.body,
signatureHeader: req.headers['x-remotion-signature'] as string,
});
// If code reaches this path, the webhook is authentic.
const payload = req.body as WebhookPayload;
if (payload.type === 'success' && onSuccess) {
await onSuccess(payload);
} else if (payload.type === 'timeout' && onTimeout) {
await onTimeout(payload);
} else if (payload.type === 'error' && onError) {
await onError(payload);
}
res.status(200).json({
success: true,
});
} catch (err) {
res.status(500).json({
success: false,
error: err instanceof Error ? err.message : String(err),
});
}
};
};
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Inspect the 'error' field of the 500 JSON response to identify which callback threw and why.
- Wrap the body of your onSuccess/onTimeout/onError callbacks in try/catch so a callback failure does not surface as a 500.
- Log the full payload and callback error server-side for diagnosis, since only the message is returned.
- If the error is from an external service, add retries/backoff inside the callback.
Example fix
// before
const handler = startWebhookHandler({
onSuccess: async (payload) => { await db.markDone(payload.renderId); }
});
// after
const handler = startWebhookHandler({
onSuccess: async (payload) => {
try { await db.markDone(payload.renderId); }
catch (e) { logger.error('onSuccess failed', e); /* do not rethrow */ }
}
}); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate payload shape before invoking callbacks
function isValidPayload(p: unknown): p is { type: string; renderId: string } {
return typeof p === 'object' && p !== null
&& typeof (p as any).type === 'string'
&& typeof (p as any).renderId === 'string';
}
if (!isValidPayload(payload)) return res.status(400).json({ success: false, error: 'bad payload' }); Type guard
const isRenderPayload = (p: unknown): p is { type: 'success'|'timeout'|'error'; renderId: string } =>
typeof p === 'object' && p !== null &&
['success','timeout','error'].includes((p as any).type) &&
typeof (p as any).renderId === 'string'; Try / catch
// Each callback must swallow its own errors so the webhook returns 200
const safe = (fn) => async (payload) => {
try { await fn(payload); }
catch (e) { logger.error('webhook callback failed', e); }
};
onSuccess: safe(handleSuccess), Prevention
- Never let callback errors bubble to the webhook boundary; wrap each handler.
- Log the full payload server-side for later diagnosis.
- Validate payload shape with a type guard before dispatch.
When it happens
Trigger: Posting a render status payload (type 'success'|'timeout'|'error') to the webhook route, and the corresponding callback (onSuccess/onTimeout/onError) throws synchronously or returns a rejected promise.
Common situations: Webhook callback tries to write to a database that is unreachable; callback parses payload fields that are missing; third-party API call inside onSuccess fails; bug in user-supplied callback code; payload shape changed across versions.
Related errors
- ${err.message}
- No 'secret' was provided to validateWebhookSignature().
- No 'body' was provided to validateWebhookSignature().
- validateWebhookSignature can only be called from Node.JS
- No webhook signature was provided
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/5ffcca9d86871dd9.
Report an issue: GitHub.