Diagnostic Queries
Symptoms
A DROP was blocked because other database objects still depend on the target — views, foreign keys, functions, columns, or sequences. PostgreSQL refuses to silently break those dependencies and raises SQLSTATE 2BP01 (dependent_objects_still_exist).
- A DETAIL line lists the dependent objects.
- A HINT usually suggests
DROP … CASCADE. - Common when dropping a table that a view or foreign key references.
What the server log shows
ERROR: cannot drop table customers because other objects depend on it
DETAIL: constraint orders_customer_id_fkey on table orders depends on table customers
HINT: Use DROP ... CASCADE to drop the dependent objects too.
Why PostgreSQL raises this — what the manual says
Section 5.14 Dependency Tracking:
“You can also write RESTRICT instead of CASCADE to get the default behavior, which is to prevent dropping objects that any other objects depend on.”
PostgreSQL records inter-object dependencies in pg_depend. A plain DROP uses RESTRICT semantics: if any non-internal object depends on the target, the drop is rejected with 2BP01 to prevent leaving dangling references.
Common causes
- A view, materialized view, or rule built on the object.
- A foreign key in another table referencing it.
- A function, trigger, or default expression that uses it.
How to fix it
- Review the DETAIL list, then drop dependents explicitly in the right order.
- Use
DROP … CASCADEonly when you understand everything it will remove. - Recreate dependents after the change, or alter rather than drop where possible.
Diagnostic query
-- What depends on this object?
SELECT classid::regclass, objid, deptype
FROM pg_depend
WHERE refobjid = 'customers'::regclass;
Related & next steps
Reference: PostgreSQL 18 Section 5.15 “Dependency Tracking”.
Thanks — noted. This helps keep the database accurate.