dotnet/wpf · error · InvalidOperationException

SR.Image_ColorContextInvalid

Error message

SR.Image_ColorContextInvalid

What it means

SafeProfileHandle.GetColorProfileHeader throws InvalidOperationException(SR.Image_ColorContextInvalid) when the underlying ICC profile handle is invalid (closed or never initialized). GetColorProfileHeader requires a live Mscms profile handle to read the PROFILEHEADER.

Solutions

  1. Check IsInvalid (or that the ColorContext loaded successfully) before calling GetColorProfileHeader
  2. Ensure the source stream/file actually contained a valid ICC profile so the handle was created
  3. Keep the ColorContext alive while reading the header; do not dispose early
  4. Catch InvalidOperationException and fall back to a default sRGB header

Example fix

// before
helper.GetColorProfileHeader(out var header);
// after
if (!helper.IsInvalid && helper.GetColorProfileHeader(out var header)) { /* use header */ }
Defensive patterns

Strategy: type-guard

Validate before calling

if (helper == null || helper.IsInvalid) throw new InvalidOperationException("Color profile handle is not initialized");

Type guard

bool CanReadHeader(SafeProfileHandle h) => h != null && !h.IsInvalid;

Try / catch

try { ok = helper.GetColorProfileHeader(out header); } catch (InvalidOperationException) { ok = false; }

Prevention

When it happens

Trigger: Calling GetColorProfileHeader on a ColorContextHelper/SafeProfileHandle whose _profileHandle is IntPtr.Zero or has been disposed, e.g. after the ColorContext was disposed or failed to load a profile.

Common situations: Using a ColorContext after disposal; a ColorContext constructed from a stream that failed to produce a profile handle; double-dispose/finalizer races in imaging pipelines.

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


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/c75125266e2858ac. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ColorContextHelper.cs:73

            // No need to get rid of the old handle as it will get GC'ed
            _profileHandle = UnsafeNativeMethodsMilCoreApi.Mscms.OpenColorProfile(
                ref profile,
                NativeMethods.PROFILE_READ,     // DesiredAccess
                NativeMethods.FILE_SHARE_READ,  // ShareMode
                NativeMethods.OPEN_EXISTING     // CreationMode
                );
        }

        /// Retrieves the profile header
        ///
        ///
        /// NOTE: This may fail. It is up to the caller to handle it by checking the bool.
        /// 
        internal bool GetColorProfileHeader(out UnsafeNativeMethods.PROFILEHEADER header)
        {
            if (IsInvalid)
            {
                throw new InvalidOperationException(SR.Image_ColorContextInvalid);
            }

            return UnsafeNativeMethodsMilCoreApi.Mscms.GetColorProfileHeader(_profileHandle, out header);
        }

        /// Retrieves the color profile from handle
        internal void GetColorProfileFromHandle(byte[] buffer, ref uint bufferSize)
        {
            Invariant.Assert(buffer == null || bufferSize <= buffer.Length);
            
            if (IsInvalid)
            {
                throw new InvalidOperationException(SR.Image_ColorContextInvalid);
            }

            // If the buffer is null, this function will return FALSE because it didn't actually copy anything. That's fine and that's
            // what we want.
            if (!UnsafeNativeMethodsMilCoreApi.Mscms.GetColorProfileFromHandle(_profileHandle, buffer, ref bufferSize) && buffer != null)

View on GitHub (pinned to 81131a70a4)