2BP01
Read PG 18 manual ↗dependent_objects_still_exist
- SQLSTATE
- 2BP01
- Condition name
- dependent_objects_still_exist
- Class
- Dependent Privilege Descriptors Still Exist
- Source macro
- ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST
- Evidence
- Observed at runtime in the source evidence
English SQLSTATE atlas: authored explanations and source/runtime evidence are separate from the manual definitions. View source ↗
At a glance
2BP01 means a DROP or related catalog operation would remove an object that other database objects still require. The useful repair is dependency-aware: identify the dependent object, decide whether it should be removed or retained, and only then retry the original operation.
Meaning
The dependency walker emits 2BP01 for a blocked object operation. In the representative path, a view depends on a table, so DROP TABLE cannot proceed. The primary message, DETAIL, and CASCADE hint are dynamically assembled from object descriptions and the dependency graph. 2BP01 is about dependent objects; 2B000 is a separate dependent-privilege-descriptor condition.
Diagnosis
Capture SQLSTATE, primary message, DETAIL, and HINT together. The DETAIL identifies the dependent view in the selected path. Inspect the view definition and dependency metadata before choosing a repair; pg_depend and pg_get_viewdef() help explain why the object is retained. In the selected explicit BEGIN block, this ERROR puts the connection in INERROR until ROLLBACK; an autocommit statement has no surrounding block to preserve. Catalog queries issued through the failed explicit block will not provide a clean diagnosis.
Response
Rollback the failed explicit transaction. If the view is intentionally disposable, drop that view first and then the table; if it is part of the schema contract, preserve it and choose a different migration. CASCADE is a deliberate request to remove dependent objects and can exceed the intended change, so the HINT is not an instruction to apply it automatically. After a dependency-aware repair, rerun the complete DDL plan and verify the surviving objects.
Messages
The selected source branch uses cannot drop %s because other objects depend on it, a dynamic internal DETAIL, and Use DROP ... CASCADE to drop the dependent objects too. The object descriptions and dependency list are runtime values; do not treat the DETAIL as a stable single-object template or assume every 2BP01 path has this exact wording.
Representative case
The runner reads this dependency sequence from verify/cases/2BP01/snippets.json (SHA-256 899e4fd9fb002fc293bd9efee0204e4f2622968c6d9460ad05eb9a0ebd3bac69). It uses an explicit BEGIN/ROLLBACK for the failed DROP and then removes the known view before its table, without CASCADE. See the public case export and structured evidence.
CREATE TABLE base_items(id integer PRIMARY KEY, payload text NOT NULL);
CREATE VIEW dependent_view AS SELECT id, payload FROM base_items;
BEGIN;
DROP TABLE base_items;
ROLLBACK;
DROP VIEW dependent_view;
DROP TABLE base_items;
SELECT to_regclass('base_items'), to_regclass('dependent_view');
The registry names are qualified by the runner inside a private schema. The final to_regclass check returns two nulls, proving that the intended objects were removed rather than silently cascading through an unknown graph.
The selected case observed 2BP01 on PostgreSQL 18.6 and 10.21. DROP TABLE reported the dependent view in DETAIL and suggested CASCADE; the explicit block was INERROR, ROLLBACK restored IDLE, and intentionally dropping the view first allowed the table to be removed.
Versions
The catalogue records this condition from the early historical boundary through the formal snapshots. The fixed 18.6 source includes dependency, shared-dependency, role, privilege, typed-table, and tablespace branches; the runtime case covers one ordinary view-to-table dependency on 18.6 and 10.21. Do not infer that a CASCADE hint is equally safe for all branches.
Sources
src.errcodes.18.6(SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.dependency.18.6(SHA-2561878f848dae03e08424a47a09508f3443227ad67c4bc5e0aba3ec9655d015b74)DROP TABLE documentation· local call scansrc.calls.REL_18_6(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)
Source evidence
Evidence belongs to the frozen source and runtime versions listed here. It is not a runtime verification of the selected manual version.
2BP01 is the dependent_objects_still_exist condition in Class 2B.
Method: Read the fixed errcodes.txt row and macro mapping.
Limits: Other dependent-privilege and typed-object paths use the same condition with different dynamic messages.
The dependency walker reports that an object cannot be dropped while other objects depend on it and supplies a CASCADE hint.
Method: Trace reportDependentObjects and its dynamic DETAIL/HINT assembly.
Limits: DETAIL names the dependency graph dynamically; it is not a fixed format for every object kind.
A safe repair identifies the dependent view and drops it intentionally before dropping its base table; CASCADE is an explicit policy choice, not a universal repair.
Method: Use a view-to-table dependency and the shared registry repair sequence.
Limits: Other dependency types and ownership/privilege checks may require a different order or privileges.
The selected 2BP01 case passed on PostgreSQL 18.6 and 10.21 with the structured SQLSTATE, transaction-state, and repair assertions recorded in the runtime entries.
Method: Read the selected runner summaries and raw outputs tied to the shared snippet registry.
Limits: The INERROR then IDLE assertion belongs to the selected explicit BEGIN/ROLLBACK block; autocommit statements have no surrounding block to preserve.
runtime.2BP01-batch34-final-20260909.latest runtime.2BP01-batch34-final-20260909.pg10
- src/backend/utils/errcodes.txt · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 raw/calls/REL_18_6.jsonl· ·- src/backend/catalog/dependency.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - doc/src/sgml/ref/drop_table.sgml · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7
Message templates
ERROR · message.dependent-object
Primary
cannot drop %s because other objects depend on it
Detail
%s (dynamic internal detail)
Hint
Use DROP ... CASCADE to drop the dependent objects too.
Object descriptions and dependency detail are dynamically assembled.
Reproduction & repair cases
dependent_object_drop_recovery · PG 10, 18
Preconditions
- A runner-owned disposable target is provisioned.
Trigger: Create a view that depends on a table, attempt DROP TABLE inside an explicit transaction, then drop the view first and the table.
Expected assertions
- SQLSTATE is 2BP01
- The diagnostic names dependent objects
- The failed transaction is INERROR until ROLLBACK
- Dropping the dependent view first removes both objects without CASCADE
Repair: Rollback the failed DROP, inspect the named dependent objects, and remove them in an intentional dependency order.
Cleanup: Drop the case schema with an owner connection.
Recorded runtime evidence
18.6 (Homebrew) · passed
Run: 2BP01-batch34-final-20260909
{
"repair": {
"remaining_relations": [
null,
null
]
},
"primary": "cannot drop table c2bp01_dependent_object_drop_recovery.base_items because other objects depend on it",
"severity": "ERROR",
"sqlstate": "2BP01",
"statuses": {
"after_error": "INERROR",
"after_repair": "IDLE",
"after_rollback": "IDLE"
},
"connection_autocommit": true
}10.21 (Debian 10.21-1.pgdg90+1) · passed
Run: 2BP01-batch34-final-20260909
{
"repair": {
"remaining_relations": [
null,
null
]
},
"primary": "cannot drop table c2bp01_dependent_object_drop_recovery.base_items because other objects depend on it",
"severity": "ERROR",
"sqlstate": "2BP01",
"statuses": {
"after_error": "INERROR",
"after_repair": "IDLE",
"after_rollback": "IDLE"
},
"connection_autocommit": true
}Definition snapshot: english-manuals:9cbb6552a6065c9b38ec1666f29… · English manual source