<@ULVA73B9P> I want to delete a flow but the delet...
# ask-marvin
t
@Marvin I want to delete a flow but the deletion fails both through the UI and the CLI.
m
thought for 142.8 seconds
A quick heads-up: in Prefect 3.x there is no
prefect flow delete
CLI command
. So if “the CLI” is failing, it’s likely either: - a custom API call/script, or - a command aimed at something else like a deployment or flow run If deletion fails both in the UI and via API/client, that usually points to a backend issue rather than a UI-only problem. What should normally happen - Deleting a flow uses the API endpoint
DELETE /flows/{id}
- Prefect should cascade-delete related deployments and flow runs automatically - Existing deployments/runs generally should not block flow deletion Common causes when flow deletion fails in both places - The backend/API is erroring during the delete - The database transaction is timing out, especially if that flow has many related runs - A server/database integrity issue - Cloud/org permission issues if the token/user lacks sufficient access - A stale/bad flow ID, though that usually gives a straightforward not-found error Important note Deployments and flow runs are *not normally blockers*; they are expected to be deleted along with the flow. Best next step: try deleting via the Python client and capture the exact error
Copy code
from prefect import get_client
import asyncio
from uuid import UUID

FLOW_ID = "your-flow-id-here"

async def main():
    async with get_client() as client:
        await client.delete_flow(UUID(FLOW_ID))
        print("Deleted")

asyncio.run(main())
If that fails, the exact traceback/error message will tell us a lot. Also useful checks 1. Confirm the flow still exists:
Copy code
from prefect import get_client
import asyncio
from uuid import UUID

FLOW_ID = "your-flow-id-here"

async def main():
    async with get_client() as client:
        flow = await client.read_flow(UUID(FLOW_ID))
        print(flow)

asyncio.run(main())
2. If this is self-hosted Prefect Server, check the API/server logs at the time of deletion. 3. If the flow has a huge number of runs, try first deleting old flow runs or associated deployments, then retry the flow deletion. Useful references - Prefect Python client / flows API behavior is implemented in the Prefect server and client codebase: Prefect repository - Prefect Cloud UI: app.prefect.cloud Can you share: - whether you’re on Prefect Cloud or self-hosted Server - the exact command or method you used for the “CLI” attempt - the exact error message from the UI/API/CLI - whether this flow has a very large run history With that, I can help narrow it down quickly.
t
$ python ./delete-flow.py Traceback (most recent call last): File "C:\transmetrics\trucking-prefect-flows\delete-flow.py", line 12, in <module> asyncio.run(main()) File "C:\Python311\Lib\asyncio\runners.py", line 190, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "C:\Python311\Lib\asyncio\runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "C:\transmetrics\trucking-prefect-flows\delete-flow.py", line 9, in main await client.delete_flow(UUID(FLOW_ID)) File "C:\Python311\Lib\site-packages\prefect\client\orchestration\_flows\client.py", line 258, in delete_flow await self.request("DELETE", "/flows/{id}", path_params={"id": flow_id}) File "C:\Python311\Lib\site-packages\prefect\client\orchestration\base.py", line 53, in request return await self._client.send(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Python311\Lib\site-packages\prefect\client\base.py", line 379, in send response.raise_for_status() File "C:\Python311\Lib\site-packages\prefect\client\base.py", line 163, in raise_for_status raise PrefectHTTPStatusError.from_httpx_error(exc) from exc.cause prefect.exceptions.PrefectHTTPStatusError: Server error '500 Internal Server Error' for url 'prefect.k8s.transmetrics.eu/api/flows/ad7112b3-a0ff-45ae-b7d0-32852538e46a' Response: {'exception_message': 'Internal Server Error'} For more information check: developer.mozilla.org/en-US/…/500 @Marvin
m
thought for 168.0 seconds
Thanks — this is helpful. A 500 from
DELETE /flows/{id}
means the problem is on the Prefect server side, not in your script. Because you’re using a self-hosted API at
<http://prefect.k8s.transmetrics.eu|prefect.k8s.transmetrics.eu>
, the next thing to check is the API server logs at the moment the delete request happens. Most likely causes in Prefect 3.x 1. An exception during event emission Prefect emits a
flow.deleted
event before finishing the delete. If event publishing fails, the whole request can return 500. 2. A slow or failing cascade delete If the flow has lots of related flow runs / states / deployments, the delete transaction can fail or time out. 3. Database/connection-pool issues Locking, pool exhaustion, or DB errors can also surface as 500s. What to do next 1. Check the Prefect API server logs Look for the traceback around the time you run the delete. If you’re on Kubernetes, something like:
Copy code
kubectl logs <prefect-api-pod> -n <namespace> --since=10m
Or if multiple pods:
Copy code
kubectl logs deployment/<prefect-api-deployment> -n <namespace> --since=10m
You want the full traceback for the
DELETE /api/flows/ad7112b3-a0ff-45ae-b7d0-32852538e46a
request. Search for terms like: -
emit
-
event
-
rollback
-
ForeignKey
-
constraint
-
TimeoutError
-
TooManyConnections
-
deadlock
2. Check how large this flow is If this flow has a huge run history, deletion may be choking on the cascade. You can test by listing the deployments and runs for that flow first. If you want, I can help you with a short script for that. 3. Try deleting deployments first Even though deployments should cascade automatically, manually removing them can reduce the amount of work in the final flow delete. If you know the deployments for that flow, try deleting them first, then retry the flow deletion. 4. If this is Postgres-backed, inspect DB locks / activity If you have DB access, check whether the delete is being blocked or timing out. For Postgres:
Copy code
SELECT pid, state, wait_event_type, wait_event, query
FROM pg_stat_activity
WHERE state <> 'idle';
And count runs for that flow:
Copy code
SELECT COUNT(*) FROM flow_run
WHERE flow_id = 'ad7112b3-a0ff-45ae-b7d0-32852538e46a';
Why I think server logs are the key here Your client traceback only shows: - request reached the API - API returned 500 - no client-side issue So the real cause is almost certainly in the server traceback. One more useful diagnostic: confirm whether all deletes fail or just this flow Try deleting: - a small test flow, or - a deployment / flow run associated with this flow That helps distinguish: - global server problem → all deletes fail - data-specific problem → only this flow fails Relevant references - Prefect repo: github.com/PrefectHQ/prefect - Prefect Cloud app: app.prefect.cloud If you can paste the API server traceback from the logs, I can help pinpoint the exact failure very quickly.