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

  1. Check the wrapper's Disposed property before each notifier call and skip/no-op if true.
  2. Re-acquire the active ScriptableBakedReflectionSystem instance at the start of each bake stage instead of holding a long-lived reference.
  3. 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

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


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/a7510d504d73e9cf. Report an issue: GitHub.