{"record":{"id":"c62dc88136690784","repo":"dotnet/wpf","slug":"sr-cannotdeleteroot","errorCode":null,"errorMessage":"SR.CanNotDeleteRoot","messagePattern":"SR\\.CanNotDeleteRoot","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageInfo.cs","lineNumber":693,"sourceCode":"        }\n    \n        // Return a reference\n        return newSubStorage;\n    }\n    \n    /// <summary>\n    /// Deletes a storage, recursively if specified.\n    /// </summary>\n    /// <param name=\"recursive\">Whether to recursive delete all existing content</param>\n    /// <param name=\"name\">Name of storage</param>\n    internal bool Delete( bool recursive , string name)\n    {\n        bool storageDeleted = false;\n        CheckDisposedStatus();\n        if( null == parentStorage )\n        {\n            // We are the root storage, you can't \"delete\" the root storage!\n            throw new InvalidOperationException(\n                SR.CanNotDeleteRoot);\n        }\n\n        if( InternalExists(name) )\n        {\n            if( !recursive && !StorageIsEmpty())\n            {\n                throw new IOException(\n                    SR.CanNotDeleteNonEmptyStorage);\n            }\n\n            InvalidateEnumerators();\n            // Go ahead and delete \"this\" storage\n            parentStorage.DestroyElement( name );\n            storageDeleted = true;\n        }\n        //We will not throw exceptions if the storage does not exist. This is to be consistent with Package.DeletePart.\n        ","sourceCodeStart":675,"sourceCodeEnd":711,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageInfo.cs#L675-L711","documentation":"Thrown by StorageInfo.Delete when attempting to delete the root storage of a compound file. The root storage has no parent (parentStorage is null), so 'deleting' it is meaningless and would leave the file object in an invalid state; the library raises InvalidOperationException to indicate a caller logic error.","triggerScenarios":"Calling Delete() or Delete(name) on the StorageRoot/root StorageInfo instance obtained from StorageRoot.OpenOnFile/OpenOnStream.","commonSituations":"Recursive cleanup code that walks a storage tree and deletes children but recurses into or mis-targets the root; generic 'delete everything' helpers that pass the root node.","solutions":["Only call Delete on non-root storages (check parentStorage != null)","Delete individual child storages/streams instead of the root; to clear a file, delete children or overwrite the file","Guard recursive cleanup with an isRoot check before invoking Delete","Close and delete the whole file at the filesystem level if the intent is to remove the package entirely"],"exampleFix":"// before\nforeach (var s in storages) s.Delete(true); // storages includes root\n// after\nforeach (var s in storages.Where(s => s != root)) s.Delete(true);","handlingStrategy":"type-guard","validationCode":"if (storage.parentStorage == null) throw new InvalidOperationException(\"Cannot delete the root storage\");","typeGuard":"bool IsRoot(StorageInfo s) => s.parentStorage == null; // skip roots in delete loops","tryCatchPattern":"try { storage.Delete(recursive); }\ncatch (InvalidOperationException ex) { /* root deletion attempt: skip or rethrow */ }","preventionTips":["Never call Delete on StorageRoot","Filter out the root in recursive tree cleanup","To remove an entire package, delete the file itself instead"],"tags":["compound-file","storage","invalid-operation","root"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}