{"record":{"id":"426426195fe2f712","repo":"apache/beam","slug":"delete-does-not-delete-containers","errorCode":null,"errorMessage":"delete does not delete containers.","messagePattern":"delete does not delete containers\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/azure/src/main/java/org/apache/beam/sdk/io/azure/blobstore/AzureBlobStoreFileSystem.java","lineNumber":412,"sourceCode":"  @Override\n  protected void rename(\n      List<AzfsResourceId> srcResourceIds,\n      List<AzfsResourceId> destResourceIds,\n      MoveOptions... moveOptions)\n      throws IOException {\n    if (moveOptions.length > 0) {\n      throw new UnsupportedOperationException(\"Support for move options is not yet implemented.\");\n    }\n    copy(srcResourceIds, destResourceIds);\n    delete(srcResourceIds);\n  }\n\n  /** This method will delete a virtual folder or a blob, not a container. */\n  @Override\n  protected void delete(Collection<AzfsResourceId> resourceIds) throws IOException {\n    for (AzfsResourceId resourceId : resourceIds) {\n      if (resourceId.getBlob() == null) {\n        throw new IOException(\"delete does not delete containers.\");\n      }\n\n      BlobContainerClient container =\n          client.get().getBlobContainerClient(resourceId.getContainer());\n\n      // deleting a blob that is not a directory\n      if (!resourceId.isDirectory()) {\n        BlobClient blob = container.getBlobClient(resourceId.getBlob());\n        if (!blob.exists()) {\n          throw new FileNotFoundException(\"The resource to delete does not exist.\");\n        }\n        blob.delete();\n      }\n\n      // deleting a directory (not a container)\n      else {\n        PagedIterable<BlobItem> blobsInDirectory =\n            container.listBlobsByHierarchy(resourceId.getBlob());","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/azure/src/main/java/org/apache/beam/sdk/io/azure/blobstore/AzureBlobStoreFileSystem.java#L394-L430","documentation":"delete() refuses to delete anything whose resourceId has no blob component, i.e. an azfs container root. Containers cannot be removed through this filesystem API (it handles virtual folders and blobs only), so it throws an IOException with this message. This prevents users from accidentally wiping a whole container via the generic delete API.","triggerScenarios":"Calling FileSystems.delete() with an AzfsResourceId whose getBlob() is null — typically a path like azfs://container or azfs://container/ that resolves to the container itself.","commonSituations":"Cleanup code that deletes directories recursively and reaches the container root; constructing resource IDs from parsed URIs that lack a blob path; users expecting container deletion like the Azure SDK's deleteContainer().","solutions":["Remove the container with the Azure SDK directly: blobContainerClient.delete() or 'az storage container delete'.","Adjust the path list to only include actual blobs / virtual directories (skip container roots).","Use a glob match (azfs://container/**) and delete only matched leaf blobs.","Add a guard in your cleanup loop that skips resources where getBlob() == null."],"exampleFix":"// before\nFileSystems.delete(ImmutableList.of(FileSystems.matchNewResource(\"azfs://mycontainer\", false))); // throws\n// after\n// delete contents via glob, or drop the container with the Azure SDK\nMatchResult all = FileSystems.match(\"azfs://mycontainer/**\");\nFileSystems.delete(all.metadata().stream().map(MatchResult.Metadata::resourceId).collect(ImmutableList.toImmutableList()));","handlingStrategy":"validation","validationCode":"// skip container-root resources before delete\nList<ResourceId> deletable = resourceIds.stream()\n    .filter(id -> !id.toString().matches(\"azfs://[^/]+/?\"))\n    .collect(Collectors.toList());\nFileSystems.delete(deletable);","typeGuard":null,"tryCatchPattern":"try {\n  FileSystems.delete(ids);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"does not delete containers\")) {\n    // drop container via Azure SDK: containerClient.delete();\n  } else { throw e; }\n}","preventionTips":["Never include the container root in recursive delete lists.","Use glob matches (azfs://container/**) to collect only blobs.","Use the Azure SDK's container client when you truly intend to drop a container."],"tags":["azure","blob-storage","delete","container","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}