remotion-dev/remotion · critical · Error
Lambda function failed with an unhandled error: See to see…
Error message
Lambda function ${functionName} failed with an unhandled error: ${event.InvokeComplete.ErrorDetails as string} See ${logs} to see the logs of this invocation. What it means
Raised by callLambdaWithStreamingResponse when the invoked Remotion Lambda returns an InvokeComplete event with ErrorCode 'Unhandled'. 'Unhandled' is AWS's marker for a crash the Lambda runtime itself could not catch: the process died (OOM, timeout kill, native crash) or an exception escaped the handler. The message embeds ErrorDetails plus a prebuilt CloudWatch Logs Insights URL filtered to this request ID.
Solutions
- Open the CloudWatch Logs Insights link in the error — it is pre-filtered to the exact request ID — and read the crash cause (Runtime.OutOfMemory, Task timed out after X seconds, etc.).
- Redeploy the function with more memory (memoryLimitMb; more memory also means more CPU) or a higher timeout, respecting the 15-minute Lambda ceiling.
- If the log shows a timeout, lower chunk size / concurrency or raise timeoutInSeconds on the render call so the function can finish within its own limit.
- If it is a transient crash, retry the render; persistent crashes point at a reproducible composition/runtime problem (test the same composition locally).
Example fix
// before
await deployFunction({region, memoryLimitMb: 2048, timeoutInSeconds: 120});
await renderMediaOnLambda({/* heavy composition */});
// after
await deployFunction({region, memoryLimitMb: 4096, timeoutInSeconds: 900});
await renderMediaOnLambda({/* heavy composition */, timeoutInSeconds: 890, concurrencyPerLambda: 2}); Defensive patterns
Strategy: retry
Try / catch
try {
await renderMediaOnLambda({...});
} catch (e) {
if (e instanceof Error && e.message.includes('failed with an unhandled error')) {
// extract the CloudWatch link from e.message, open it,
// bump memoryLimitMb/timeout and retry once
} else throw e;
} Prevention
- Deploy with memoryLimitMb >= 4096 and a timeout below the 15-minute Lambda ceiling for heavy compositions.
- Keep a CloudWatch Logs Insights link (as embedded in this error) in your runbooks for instant triage.
- Smoke-test new compositions at low concurrency before full renders to catch OOM patterns early.
- Set render timeoutInSeconds below the function timeout so renders fail gracefully instead of the function being killed.
When it happens
Trigger: Any render/payload API call (renderMediaOnLambda, renderStillOnLambda, getRenderProgress bootstrap, etc.) where the Remotion function crashes: memoryLimitMb too low so Chromium is OOM-killed, timeoutInSeconds exceeded (Lambda enforces a hard cap), or an unhandled exception in the function runtime outside Remotion's handler try/catch.
Common situations: Rendering memory-heavy compositions with default 2048 MB; timeoutInSeconds larger than the function's configured timeout; a broken custom layer or incompatible architecture causing the runtime to die; transient AWS capacity issues killing the sandbox.
Related errors
- Render did not finish yet
- AWS Caller Identity partition
- AWS Concurrency limit reached
- AWS did not return a runtime version ARN.
- Cannot cancel render
AI-assisted analysis of remotion-dev/remotion@10db9de073 (2026-08-22).
Data as JSON: /api/errors/f4bb21b186f99573.
Report an issue: GitHub.
Appendix: source
Thrown at packages/lambda-client/src/call-lambda-streaming.ts:170
try {
for await (const event of events) {
// There are two types of events you can get on a stream.
// `PayloadChunk`: These contain the actual raw bytes of the chunk
// It has a single property: `Payload`
if (event.PayloadChunk && event.PayloadChunk.Payload) {
// Awaiting applies backpressure to the response stream when the
// payload is being streamed to a sink
await onData(event.PayloadChunk.Payload);
}
if (event.InvokeComplete) {
if (event.InvokeComplete.ErrorCode) {
const {consoleDomain} = getAwsRegionMetadata(region as AwsRegion);
const logs = `https://${region}.${consoleDomain}/cloudwatch/home?region=${region}#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40requestId*2c*20*40message*0a*7c*20filter*20*40requestId*20like*20*${res.$metadata.requestId}*22*0a*7c*20sort*20*40timestamp*20asc~source~(~'*2faws*2flambda*2f${functionName}))`;
if (event.InvokeComplete.ErrorCode === 'Unhandled') {
throw new Error(
`Lambda function ${functionName} failed with an unhandled error: ${
event.InvokeComplete.ErrorDetails as string
} See ${logs} to see the logs of this invocation.`,
);
}
throw new Error(
`Lambda function ${functionName} failed with error code ${event.InvokeComplete.ErrorCode}: ${event.InvokeComplete.ErrorDetails}. See ${logs} to see the logs of this invocation.`,
);
}
}
// Don't put a `break` statement here, as it will cause the socket to not properly exit.
}
} finally {
// @ts-expect-error - We are adding a listener to a global variable
if (globalThis._dumpUnreleasedBuffers) {
// @ts-expect-error - We are adding a listener to a global variableView on GitHub (pinned to 10db9de073)