{"record":{"id":"e97f0fee1f8546dc","repo":"remotion-dev/remotion","slug":"output-file-params-key-in-bucket-params-bu","errorCode":null,"errorMessage":"Output file \"${params.key}\" in bucket \"${params.bucketName}\" already exists. Delete it before re-rendering, or set the 'overwrite' option in renderMediaOnLambda() to overwrite it.","messagePattern":"Output file \"(.+?)\" in bucket \"(.+?)\" already exists\\. Delete it before re-rendering, or set the 'overwrite' option in renderMediaOnLambda\\(\\) to overwrite it\\.","errorType":"exception","errorClass":null,"httpStatus":412,"severity":"error","filePath":"packages/lambda-client/src/write-file.ts","lineNumber":127,"sourceCode":"\t}\n};\n\nconst writeFileWithRetries = async (\n\tparams: WriteFileInput<AwsProvider> & {\n\t\tretries?: number;\n\t\tifNotExists: boolean;\n\t},\n): Promise<void> => {\n\tconst remainingRetries = params.retries ?? 2;\n\ttry {\n\t\tawait tryLambdaWriteFile(params);\n\t} catch (err) {\n\t\tif (\n\t\t\tparams.ifNotExists &&\n\t\t\t(err as {$metadata: {httpStatusCode: number} | undefined}).$metadata\n\t\t\t\t?.httpStatusCode === 412\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Output file \"${params.key}\" in bucket \"${params.bucketName}\" already exists. Delete it before re-rendering, or set the 'overwrite' option in renderMediaOnLambda() to overwrite it.`,\n\t\t\t\t{cause: err},\n\t\t\t);\n\t\t}\n\n\t\t// A failed upload may have consumed a Readable, and we cannot recreate it here.\n\t\t// Retrying it could upload an empty body and mask the original error.\n\t\tconst bodyCanBeRetried =\n\t\t\ttypeof params.body === 'string' || params.body instanceof Uint8Array;\n\t\tif (remainingRetries === 0 || !bodyCanBeRetried) {\n\t\t\tthrow err;\n\t\t}\n\n\t\tconst backoff = 2 ** (2 - remainingRetries) * 2000;\n\t\tawait new Promise((resolve) => {\n\t\t\tsetTimeout(resolve, backoff);\n\t\t});\n","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/lambda-client/src/write-file.ts#L109-L145","documentation":"This error is thrown by writeFileWithRetries when an S3 upload with the ifNotExists (conditional) option fails with HTTP status 412 Precondition Failed, meaning an object already exists at the destination key. Remotion Lambda refuses to silently overwrite existing render outputs, so the render fails fast. The original upload error is attached as `cause`.","triggerScenarios":"Calling renderMediaOnLambda() (or the internal lambdaWriteFileIfNotExists path) with an output key whose object already exists in the bucket, while the overwrite/ifNotExists behavior is active, so S3 returns 412 and this error replaces it.","commonSituations":"Re-rendering to the same output key after a previous render; a prior failed/partial render left the file behind; reusing a fixed key across runs instead of a unique render id; forgetting to pass overwrite: true.","solutions":["Delete the existing object from the S3 bucket (console, aws s3 rm, or DeleteObject) before rendering again","Pass overwrite: true to renderMediaOnLambda() so the existing object is replaced","Use a unique output key per render (e.g. include the render id or timestamp) instead of a fixed key","Catch this error and redirect output to a different key"],"exampleFix":"// before\nawait renderMediaOnLambda({\n  composition: 'MyComp',\n  serveUrl: bundleUrl,\n  codec: 'h264',\n  inputProps: {},\n  downloadName: 'out/video.mp4',\n});\n// after\nawait renderMediaOnLambda({\n  composition: 'MyComp',\n  serveUrl: bundleUrl,\n  codec: 'h264',\n  inputProps: {},\n  downloadName: 'out/video.mp4',\n  overwrite: true,\n});","handlingStrategy":"try-catch","validationCode":"import {getRenderProgress} from '@remotion/lambda-client';\nimport {HeadObjectCommand, S3Client} from '@aws-sdk/client-s3';\nconst s3 = new S3Client({});\nasync function outputExists(bucket: string, key: string) {\n  try {\n    await s3.send(new HeadObjectCommand({Bucket: bucket, Key: key}));\n    return true;\n  } catch {\n    return false;\n  }\n}","typeGuard":"const isOutputAlreadyExists = (e: unknown): e is Error & {cause: {$metadata?: {httpStatusCode?: number}}} => e instanceof Error && (e as {cause?: {$metadata?: {httpStatusCode?: number}}}).cause?.$metadata?.httpStatusCode === 412;","tryCatchPattern":"try {\n  await renderMediaOnLambda(params);\n} catch (err) {\n  if (String(err).includes('already exists')) {\n    await renderMediaOnLambda({...params, overwrite: true});\n  } else {\n    throw err;\n  }\n}","preventionTips":["Pass overwrite: true when re-rendering to a fixed key","Derive output keys from the render id or a timestamp so they are unique per run","Head-check the S3 key before rendering when you need to detect leftovers","Clean up stale outputs from failed renders before retrying"],"tags":["s3","lambda","file-already-exists","render"],"backgroundTag":"file-already-exists","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}