stride3d/stride · error · InvalidOperationException
Bundle has not been loaded.
Error message
Bundle has not been loaded.
What it means
UnloadBundleRecursive searches loadedBundles for the bundle description being unloaded and throws InvalidOperationException when none matches (loadedBundleIndex == -1). The code attempted to unload a bundle that was never loaded (or already fully unloaded).
Solutions
- Track loaded bundles and only call UnloadBundle for bundles previously loaded successfully.
- Make unload logic idempotent: skip if the bundle is not currently loaded instead of assuming it is.
- Fix double-dispose (guard Dispose with a flag) so unload doesn't run twice.
Example fix
// before
backend.UnloadBundle("scene.bundle"); // may throw if never loaded
// after
if (backend.IsBundleLoaded("scene.bundle"))
backend.UnloadBundle("scene.bundle"); Defensive patterns
Strategy: validation
Validate before calling
if (!backend.IsBundleLoaded(bundleUrl))
return; // nothing to unload
backend.UnloadBundle(bundleUrl); Try / catch
try
{
backend.UnloadBundle(bundleUrl);
}
catch (InvalidOperationException ex) when (ex.Message == "Bundle has not been loaded.")
{
// already unloaded; treat as no-op
} Prevention
- Track load/unload pairs in your own reference counting or use a loaded-set.
- Guard Dispose against double execution so unload paths run once.
- Let recursive unloading handle dependencies rather than unloading children manually.
When it happens
Trigger: Calling UnloadBundle for a bundle name/url never passed to LoadBundle, unloading the same bundle twice, or recursive unloading reaching a dependency already unloaded.
Common situations: Shutdown/dispose logic running twice (double Dispose), error-recovery paths that unload bundles after a failed load, or unloading a bundle whose parent already recursively removed it.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Unable to unload the current profile.
- Can't pack files.
- Cannot resize the manifold store, manifolds have not been…
- Not initialized.
- Not running.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/9aaa37e53bddd37c.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Serialization/Storage/BundleOdbBackend.cs:299
{
if (bundleName == null) throw new ArgumentNullException(nameof(bundleName));
lock (loadedBundles)
{
int loadedBundleIndex = -1;
for (int index = 0; index < loadedBundles.Count; index++)
{
var currentBundle = loadedBundles[index];
if (currentBundle.BundleName == bundleName)
{
loadedBundleIndex = index;
break;
}
}
if (loadedBundleIndex == -1)
throw new InvalidOperationException("Bundle has not been loaded.");
var loadedBundle = loadedBundles[loadedBundleIndex];
var bundle = loadedBundle.Description;
if (--loadedBundle.ReferenceCount == 0)
{
// Remove and dispose stream from pool
lock (loadedBundle.Streams)
{
for (int index = 0; index < loadedBundle.Streams.Count; index++)
{
var stream = loadedBundle.Streams[index];
stream?.Dispose();
loadedBundle.Streams[index] = null;
}
}
// Actually unload bundle
loadedBundles.RemoveAt(loadedBundleIndex);View on GitHub (pinned to 96fad776d2)