{"record":{"id":"76121aed90cbdaf0","repo":"remotion-dev/remotion","slug":"cannot-cancel-render-renderid-the-render-was-n","errorCode":null,"errorMessage":"Cannot cancel render {$renderId}: The render was not started with enableCancellation: true.","messagePattern":"Cannot cancel render (.+?): The render was not started with enableCancellation: true\\.","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"packages/lambda-php/src/PHPClient.php","lineNumber":311,"sourceCode":"        $result = $this->invokeLambdaFunction($payload);\n        return $this->handleLambdaResponseProgress($result);\n    }\n\n    public function cancelRenderOnLambda(string $renderId, string $bucketName): void\n    {\n        try {\n            $progress = json_decode(\n                $this->readProgressFromS3($bucketName, \"renders/{$renderId}/progress.json\"),\n                true,\n                512,\n                JSON_THROW_ON_ERROR\n            );\n        } catch (\\Throwable $exception) {\n            throw new Exception(\"Could not read progress for render {$renderId}: {$exception->getMessage()}\", 0, $exception);\n        }\n\n        if (($progress['cancellationEnabled'] ?? false) !== true) {\n            throw new InvalidArgumentException(\n                \"Cannot cancel render {$renderId}: The render was not started with enableCancellation: true.\"\n            );\n        }\n\n        try {\n            $this->writeCancellationToS3(\n                $bucketName,\n                \"renders/{$renderId}/cancel.json\",\n                json_encode(\n                    ['cancelledAt' => (int) floor(microtime(true) * 1000)],\n                    JSON_THROW_ON_ERROR\n                )\n            );\n        } catch (\\Throwable $exception) {\n            throw new Exception(\"Could not cancel render {$renderId}: {$exception->getMessage()}\", 0, $exception);\n        }\n    }\n","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/remotion-dev/remotion/blob/10db9de07356446fb0edb3c3ae211369b693d18b/packages/lambda-php/src/PHPClient.php#L293-L329","documentation":"Thrown by PHPClient::cancelRenderOnLambda() (packages/lambda-php/src/PHPClient.php). Before writing the cancellation flag, the method downloads renders/{renderId}/progress.json from the render bucket and requires cancellationEnabled to be exactly true. Remotion Lambda makes cancellation opt-in (it adds overhead to the render), so only renders started with enableCancellation: true can be canceled; anything else is rejected with this InvalidArgumentException.","triggerScenarios":"Calling $client->cancelRenderOnLambda($renderId, $bucketName) for a render started via renderMediaOnLambda() whose RenderParams left enableCancellation at its default of false (packages/lambda-php/src/RenderParams.php sets protected $enableCancellation = false), i.e. the params object was never configured with setEnableCancellation(true).","commonSituations":"Starting a long render and only then deciding to cancel it; passing enableCancellation into inputProps or the wrong options array instead of RenderParams; helper code copied from a template that predates the option; deployed Remotion Lambda functions older than the PHP client so progress.json never contains the field.","solutions":["For any new render, opt in at render time: call $renderParams->setEnableCancellation(true) (or pass enableCancellation: true when constructing RenderParams) before renderMediaOnLambda().","For the currently running render there is no remedy - it was not started cancellable. Let it finish, or abandon its output and start a new render with the flag enabled.","Verify the flag took effect: download renders/{renderId}/progress.json from the render bucket and confirm cancellationEnabled is exactly true.","If progress.json has no cancellationEnabled field at all, your deployed Remotion Lambda functions are older than the PHP client - update them (npx remotion lambda update) so client and functions match."],"exampleFix":"// before\n$renderParams = new RenderParams();\n// ... composition, codec, etc. - enableCancellation never set (defaults to false)\n$response = $client->renderMediaOnLambda($renderParams);\n$client->cancelRenderOnLambda($response['renderId'], $response['bucketName']); // throws\n\n// after\n$renderParams = new RenderParams();\n$renderParams->setEnableCancellation(true);\n$response = $client->renderMediaOnLambda($renderParams);\n$client->cancelRenderOnLambda($response['renderId'], $response['bucketName']); // works","handlingStrategy":"validation","validationCode":"// Render time - decide cancellability before starting, in one factory\n$renderParams = new RenderParams();\n$renderParams->setEnableCancellation(true); // required for cancelRenderOnLambda()\n$response = $client->renderMediaOnLambda($renderParams);\n\n// Cancel time - optionally verify progress.json before calling cancel\n$progress = json_decode(\n    file_get_contents(\"https://{$bucketName}.s3.{$region}.amazonaws.com/renders/{$renderId}/progress.json\"),\n    true\n);\nif (($progress['cancellationEnabled'] ?? false) !== true) {\n    // do not call cancelRenderOnLambda() - it will throw\n}","typeGuard":null,"tryCatchPattern":"try {\n    $client->cancelRenderOnLambda($renderId, $bucketName);\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'enableCancellation')) {\n        // render is not cancellable - surface a clear message to the user\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Build all RenderParams through one factory in your codebase that sets enableCancellation(true) whenever cancellation may be needed.","Treat cancellability as a render-time decision - it cannot be added to a running render.","Keep a renderId-to-params mapping so you know which renders are cancellable before attempting cancel."],"tags":["lambda","cancellation","php","opt-in","progress-json","s3"],"backgroundTag":"opt-in-flag-required","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"}