{"record":{"id":"c5b1ea27534798ed","repo":"remotion-dev/remotion","slug":"could-not-cancel-render-render-id-error","errorCode":null,"errorMessage":"Could not cancel render {render_id}: {error}","messagePattern":"Could not cancel render (.+?): (.+?)","errorType":"exception","errorClass":"RemotionException","httpStatus":null,"severity":"error","filePath":"packages/lambda-python/remotion_lambda/remotionclient.py","lineNumber":658,"sourceCode":"            raise RemotionException(\n                f\"Could not read progress for render {render_id}: {error}\"\n            ) from error\n\n        if progress.get('cancellationEnabled') is not True:\n            raise RemotionInvalidArgumentException(\n                f\"Cannot cancel render {render_id}: The render was not started \"\n                \"with enableCancellation: true.\"\n            )\n\n        try:\n            s3_client.put_object(\n                Bucket=bucket_name,\n                Key=f\"renders/{render_id}/cancel.json\",\n                Body=json.dumps({'cancelledAt': int(time.time() * 1000)}),\n                ContentType='application/json',\n            )\n        except ClientError as error:\n            raise RemotionException(\n                f\"Could not cancel render {render_id}: {error}\"\n            ) from error\n\n    def render_still_on_lambda(\n        self, render_params: RenderStillParams\n    ) -> Optional[RenderStillResponse]:\n        \"\"\"\n        Render still using AWS Lambda.\n\n        Args:\n            render_params (RenderStillParams): Render parameters.\n\n        Returns:\n            Optional[RenderStillResponse]: Response from the render operation, or None if no body object.\n        \"\"\"\n        params_json_str = self.construct_render_request(render_params, render_type='still') # Using Enum member\n\n        body_object = self._invoke_lambda(","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/remotion-dev/remotion/blob/10db9de07356446fb0edb3c3ae211369b693d18b/packages/lambda-python/remotion_lambda/remotionclient.py#L640-L676","documentation":"After the opt-in check passes, cancel_render_on_lambda() writes renders/{render_id}/cancel.json via s3_client.put_object(...). A ClientError from that PUT is wrapped as RemotionException 'Could not cancel render ...' with the boto3 error chained as __cause__.","triggerScenarios":"Credentials without s3:PutObject on the bucket's renders/* prefix; wrong bucket_name or region argument; the bucket deleted; an endpoint or network failure during the PUT.","commonSituations":"Read-only AWS keys used by the script that cancels renders; bucket policies restricting writes to specific roles; VPC endpoint policies blocking S3 writes from the canceling workload.","solutions":["Read the chained boto3 error (__cause__) - its code (AccessDenied, NoSuchBucket, SlowDown) identifies the cause.","Grant s3:PutObject on arn:aws:s3:::<bucket>/renders/* to the credentials the Python client uses.","Confirm bucket_name and region arguments match the ones the render used (take them from the render response).","Retry on transient codes (5xx, SlowDown) - writing cancel.json again is harmless."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import boto3\nfrom botocore.exceptions import ClientError\n\ns3 = boto3.client(\"s3\", region_name=region)\ntry:\n    s3.put_object(Bucket=bucket_name, Key=\"renders/_cancel-write-test\", Body=\"{}\")\n    s3.delete_object(Bucket=bucket_name, Key=\"renders/_cancel-write-test\")\nexcept ClientError as e:\n    raise RuntimeError(f\"Cancel path cannot write to S3: {e}\") from e","typeGuard":null,"tryCatchPattern":"from remotion_lambda.errors import RemotionException\n\nfor attempt in range(2):\n    try:\n        client.cancel_render_on_lambda(render_id, bucket_name)\n        break\n    except RemotionException as e:\n        cause = e.__cause__\n        code = getattr(getattr(cause, \"response\", {}), \"get\", lambda *a: None)(\"Error\", {}).get(\"Code\")\n        if attempt == 0 and code in (\"SlowDown\", \"RequestTimeout\", \"InternalError\"):\n            continue  # transient - retry once\n        if code == \"AccessDenied\":\n            raise RuntimeError(\"Grant s3:PutObject on renders/* to the cancel credentials\") from e\n        raise","preventionTips":["Give the canceling workload the same S3 write permissions the renderer has (s3:PutObject on renders/*).","Reuse bucket/region from the render response object instead of re-passing them by hand.","The cancel write is idempotent - a retry after a transient failure is always safe."],"tags":["lambda","python","s3","iam-permissions","cancellation","boto3"],"backgroundTag":"s3-putobject-denied","analyzedSha":"10db9de07356446fb0edb3c3ae211369b693d18b","analyzedAt":"2026-08-22T21:45:17.748Z","contentChangedAt":"2026-08-22T21:45:17.748Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}