stride3d/stride · error · InvalidOperationException
Package RootDirectory is null
Error message
Package RootDirectory is null
What it means
This internal refresh helper (CollectFiles) requires package.RootDirectory to be set before it can enumerate files for the package. A null RootDirectory means the package has no root folder association, so enumeration is impossible and it throws InvalidOperationException.
Solutions
- Set package.RootDirectory to the package's folder before refreshing
- Ensure the package is loaded via the normal load pipeline so RootDirectory is populated
- Skip refresh for in-memory packages without a root directory
Example fix
// before
RefreshPackageFiles(newInMemoryPackage);
// after
if (newInMemoryPackage.RootDirectory is null)
newInMemoryPackage.RootDirectory = packageFolder;
RefreshPackageFiles(newInMemoryPackage); Defensive patterns
Strategy: type-guard
Validate before calling
if (package.RootDirectory is null) throw new InvalidOperationException("Set RootDirectory before refresh"); Type guard
bool CanRefresh(Package p) => p.RootDirectory is not null && Directory.Exists(p.RootDirectory);
Try / catch
try { RefreshPackageFiles(pkg); } catch (InvalidOperationException ex) when (ex.Message.Contains("RootDirectory")) { pkg.RootDirectory = rootFolder; RefreshPackageFiles(pkg); } Prevention
- Never refresh in-memory packages without a root directory
- Populate RootDirectory when constructing Package objects programmatically
- Assert RootDirectory in package load tests
When it happens
Trigger: Calling the package file-collection/refresh routine on a Package instance whose RootDirectory property is null — typically a package not loaded from/saved to disk.
Common situations: Programmatically constructed in-memory Package objects passed to refresh; deserialization that omitted RootDirectory; packages loaded from sources that don't set the root.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- No Collection item identifier associated to the given…
- IsObjectReference returned true for an object that is not…
- Asset of type was migrated, but still its new version…
- Expecting relative path
- File doesn't appear to be a valid package
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/7c5c79a08202f858.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/Package.cs:1238
foreach (var folder in AssetFolders)
{
var folderPath = RootDirectory is not null ? UPath.Combine(RootDirectory, folder.Path) : folder.Path;
if (!existingAssetFolders.Contains(folderPath))
{
existingAssetFolders.Add(folderPath);
}
}
return existingAssetFolders;
}
public static List<PackageLoadingAssetFile> ListAssetFiles(Package package, bool listAssetsInMsbuild, bool listUnregisteredAssets)
{
var listFiles = new List<PackageLoadingAssetFile>();
// TODO Check how to handle refresh correctly as a public API
if (package.RootDirectory is null)
{
throw new InvalidOperationException("Package RootDirectory is null");
}
if (!Directory.Exists(package.RootDirectory))
{
return listFiles;
}
// Iterate on each source folders
foreach (var sourceFolder in package.GetDistinctAssetFolderPaths())
{
// Lookup all files
foreach (var directory in FileUtility.EnumerateDirectories(sourceFolder, SearchDirection.Down))
{
foreach (var filePath in directory.GetFiles())
{
// Don't load package via this method
if (filePath.FullName.EndsWith(PackageFileExtension, StringComparison.OrdinalIgnoreCase))
{View on GitHub (pinned to 96fad776d2)