{"record":{"id":"65a727ecbb4a2924","repo":"apache/iceberg","slug":"namespace-s-is-not-empty-contains-d-child-names","errorCode":null,"errorMessage":"Namespace %s is not empty. Contains %d child namespace(s).","messagePattern":"Namespace (.+?) is not empty\\. Contains (.+?) child namespace\\(s\\)\\.","errorType":"exception","errorClass":"NamespaceNotEmptyException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java","lineNumber":225,"sourceCode":"      namespaces.put(namespace, ImmutableMap.copyOf(metadata));\n    }\n  }\n\n  @Override\n  public boolean namespaceExists(Namespace namespace) {\n    return namespaces.containsKey(namespace);\n  }\n\n  @Override\n  public boolean dropNamespace(Namespace namespace) throws NamespaceNotEmptyException {\n    synchronized (this) {\n      if (!namespaceExists(namespace)) {\n        return false;\n      }\n\n      List<Namespace> childNamespaces = listNamespaces(namespace);\n      if (!childNamespaces.isEmpty()) {\n        throw new NamespaceNotEmptyException(\n            \"Namespace %s is not empty. Contains %d child namespace(s).\",\n            namespace, childNamespaces.size());\n      }\n\n      List<TableIdentifier> tableIdentifiers = listTables(namespace);\n      if (!tableIdentifiers.isEmpty()) {\n        throw new NamespaceNotEmptyException(\n            \"Namespace %s is not empty. Contains %d table(s).\", namespace, tableIdentifiers.size());\n      }\n\n      List<TableIdentifier> viewIdentifiers = listViews(namespace);\n      if (!viewIdentifiers.isEmpty()) {\n        throw new NamespaceNotEmptyException(\n            \"Namespace %s is not empty. Contains %d view(s).\", namespace, viewIdentifiers.size());\n      }\n\n      return namespaces.remove(namespace) != null;\n    }","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java#L207-L243","documentation":"InMemoryCatalog.dropNamespace throws NamespaceNotEmptyException when the namespace still contains child namespaces. The catalog refuses to drop a namespace that would orphan nested namespaces, forcing explicit removal of children first.","triggerScenarios":"Calling catalog.dropNamespace(ns) when listNamespaces(ns) returns one or more child namespaces. E.g. dropping 'a' while 'a.b' still exists.","commonSituations":"Hierarchical namespace layouts (multi-level namespaces) where cleanup only removed tables but not nested namespaces; teardown scripts running in the wrong order.","solutions":["Drop all child namespaces recursively before dropping the parent","List children with listNamespaces(namespace) and iterate dropNamespace","Drop tables in each child namespace first to avoid chained NotEmpty errors","Catch NamespaceNotEmptyException if partial cleanup is acceptable"],"exampleFix":"// before\ncatalog.dropNamespace(Namespace.of(\"parent\"));\n// after\nNamespace ns = Namespace.of(\"parent\");\nfor (Namespace child : catalog.listNamespaces(ns)) {\n  catalog.dropNamespace(child);\n}\ncatalog.dropNamespace(ns);","handlingStrategy":"validation","validationCode":"if (!catalog.listNamespaces(namespace).isEmpty()) { throw new IllegalStateException(\"Drop child namespaces first\"); }\ncatalog.dropNamespace(namespace);","typeGuard":null,"tryCatchPattern":"try { catalog.dropNamespace(ns); } catch (NamespaceNotEmptyException e) { /* recursively drop children then retry */ }","preventionTips":["Write recursive teardown: drop tables, then child namespaces, then parent","List children with listNamespaces before dropping","Order cleanup deepest-first in hierarchical namespaces","Model cleanup as a helper so no path skips nested namespaces"],"tags":["inmemory-catalog","namespace","not-empty"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}