stride3d/stride · error · InvalidOperationException
System packages cannot be deleted.
Error message
System packages cannot be deleted.
What it means
PackageViewModel.Delete removes a package from the session, but system/read-only packages (Package.IsReadOnly) are protected. It throws InvalidOperationException because deleting such packages would break the loaded project's system dependencies.
Solutions
- Check Package.IsReadOnly before calling Delete and skip read-only packages
- Remove the package from user-editable selections
- Only delete packages that are direct user dependencies
Example fix
// before packageViewModel.Delete(); // after if (!packageViewModel.Package.IsReadOnly) packageViewModel.Delete();
Defensive patterns
Strategy: validation
Validate before calling
if (packageViewModel.Package.IsReadOnly) throw new InvalidOperationException("System packages cannot be deleted"); Type guard
bool CanDelete(PackageViewModel p) => !p.Package.IsReadOnly;
Try / catch
try { p.Delete(); } catch (InvalidOperationException) { /* read-only system package */ } Prevention
- Check IsReadOnly before deleting
- Exclude system packages from selections
- Handle read-only packages in bulk deletes
When it happens
Trigger: Calling Delete() on a PackageViewModel whose Package.IsReadOnly is true — e.g. a system package like Stride core assets.
Common situations: Selecting a system package in the solution explorer and deleting it; bulk-delete operations that include read-only packages.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Cannot change the name of a EntityHierarchyRootViewModel…
- Cannot create a read-only Depth-Stencil View. Not supported…
- Cannot delete a MountPointViewModel
- Cannot deserialize collection to readonly collection type
- Cannot initialize a read-only Depth-Stencil Buffer. Not…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/e30b7a66b19d4e26.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Core.Assets.Editor/ViewModel/PackageViewModel.cs:380
}
private static bool CheckDependsOnRecursively(PackageViewModel source, PackageViewModel target, List<PackageViewModel> visitedPackages)
{
visitedPackages.Add(source);
return source.Dependencies.Content.Any(x => x.Target == target) || source.Dependencies.Content.Select(x => x.Target).NotNull().Where(x => !visitedPackages.Contains(x)).Any(x => CheckDependsOnRecursively(x, target, visitedPackages));
}
public void MoveAsset(AssetViewModel asset, DirectoryBaseViewModel directory)
{
asset.MoveAsset(Package, directory);
}
public void Delete()
{
if (Package.IsReadOnly)
{
// Note: this should never happen (see comments in method SessionViewModel.DeleteSelectedSolutionItems)
throw new InvalidOperationException("System packages cannot be deleted.");
}
using (var transaction = UndoRedoService.CreateTransaction())
{
string message = $"Delete package '{Name}'";
IsDeleted = true;
UndoRedoService.SetName(transaction, message);
}
}
public void CheckConsistency()
{
// Only compare referenceable assets: non-referenceable ones (e.g. scripts) are indexed
// differently and must be filtered on both sides, otherwise they always appear inconsistent.
static bool IsReferenceable(Asset asset) => asset.GetType().GetCustomAttribute<AssetDescriptionAttribute>()?.Referenceable ?? true;
var assetList = Package.Assets.Where(item => IsReferenceable(item.Asset)).ToDictionary(x => x.Location.FullPath);
var assetViewModels = Assets.Where(x => IsReferenceable(x.AssetItem.Asset)).ToList();
var logger = Session.AssetLog.GetLogger(LogKey.Get("Consistency"));View on GitHub (pinned to 96fad776d2)