Unity-Technologies/UnityCsReference · error · ObjectDisposedException
ScriptableBakedReflectionSystemWrapper
Error message
ScriptableBakedReflectionSystemWrapper
What it means
Thrown as ObjectDisposedException with the wrapper type name by the IScriptableBakedReflectionSystemStageNotifier.EnterStage implementation when the underlying native wrapper has already been disposed. The wrapper holds a native IntPtr (m_Ptr) that is zeroed on Dispose, so calling EnterStage after disposal dereferences dead state and is explicitly rejected. Disposal typically happens when the editor releases the baked reflection system between bakes or on domain reload.
Source
Thrown at Editor/Mono/Camera/ScriptableBakedReflectionSystemWrapper.bindings.cs:56
get { return implementation != null ? implementation.stateHashes : null; }
}
int Internal_ScriptableBakedReflectionSystemWrapper_stageCount
{
[RequiredByNativeCode]
get { return implementation != null ? implementation.stageCount : 0; }
}
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
void IScriptableBakedReflectionSystemStageNotifier.EnterStage(int stage, string progressMessage, float progress)
{
if (Disposed)
throw new ObjectDisposedException("ScriptableBakedReflectionSystemWrapper");
ScriptingEnterStage(m_Ptr, stage, progressMessage, progress);
}
void IScriptableBakedReflectionSystemStageNotifier.ExitStage(int stage)
{
if (Disposed)
throw new ObjectDisposedException("ScriptableBakedReflectionSystemWrapper");
ScriptingExitStage(m_Ptr, stage);
}
void IScriptableBakedReflectionSystemStageNotifier.SetIsDone(bool isDone)
{
if (Disposed)
throw new ObjectDisposedException("ScriptableBakedReflectionSystemWrapper");
ScriptingSetIsDone(m_Ptr, isDone);View on GitHub (pinned to 225b0fbdb5)
Solutions
- Check the wrapper's Disposed property before each notifier call and skip/no-op if true.
- Re-acquire the active ScriptableBakedReflectionSystem instance at the start of each bake stage instead of holding a long-lived reference.
- Tie notifier usage to a using scope or the bake request lifetime so Dispose ordering prevents post-dispose calls.
Example fix
// before
stageNotifier.EnterStage(stage, msg, progress);
// after
if (!wrapper.Disposed)
stageNotifier.EnterStage(stage, msg, progress); Defensive patterns
Strategy: validation
Validate before calling
if (wrapper == null || wrapper.Disposed) return; ((IScriptableBakedReflectionSystemStageNotifier)wrapper).EnterStage(stage, msg, progress);
Try / catch
try { notifier.EnterStage(stage, msg, progress); }
catch (ObjectDisposedException) { /* system torn down; abort bake */ } Prevention
- Check Disposed before each notifier call.
- Re-acquire the active system per bake rather than caching long-term.
- Avoid capturing the notifier in long-lived async contexts.
When it happens
Trigger: Calling stageNotifier.EnterStage(stage, progressMessage, progress) on a ScriptableBakedReflectionSystemWrapper instance whose Dispose(bool) has run (m_Ptr == IntPtr.Zero). This occurs when a long-running bake coroutine keeps a reference to the notifier past the system's lifecycle, or after an editor assembly reload invalidates the native handle.
Common situations: Custom ScriptableBakedReflectionSystem implementations that cache the stage notifier and call EnterStage across editor play-mode toggles, domain reloads, or after the user cancels and the system is torn down. Stale references captured in closures or background tasks.
Related errors
- Not a valid handle, has it been released already?
- {RegisterRenderPickingCallback} cannot be called during pick
- {UnregisterRenderPickingCallback} cannot be called during pi
- gameObject
- Cannot save to clip as there is nothing to save. The method
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/a7510d504d73e9cf.
Report an issue: GitHub.