dotnet/machinelearning · error · InvalidOperationException
Object is disposed.
Error message
Object is disposed.
What it means
MLImage wraps a disposable SKBitmap; ThrowInvalidOperationExceptionIfDisposed is called at the start of most members (PixelFormat, GetBGRPixels, Pixels, Tag, Width, Height, Save, etc.). Once Dispose ran, _image is null and any member access throws 'Object is disposed.'
Solutions
- Do not call members after Dispose; keep the image alive for its entire usage scope
- Re-load the image (MLImage.CreateFromFile) if it was disposed prematurely
- Wrap access in try-catch for InvalidOperationException and treat as a lifecycle bug
- Check ObjectDisposed-like state via try/catch since MLImage exposes no IsDisposed property
Example fix
// before using var image = MLImage.CreateFromFile(path); DoWork(image); // disposed here, then: var w = image.Width; // throws // after MLImage image = MLImage.CreateFromFile(path); var w = image.Width; DoWork(image); image.Dispose();
Defensive patterns
Strategy: try-catch
Validate before calling
// no public IsDisposed; track ownership yourself bool usable = image != null && !_ownsAndDisposedSet.Contains(image);
Type guard
static bool IsUsable(MLImage img) => img is not null; // track Dispose calls in your own wrapper
Try / catch
try { var w = image.Width; } catch (InvalidOperationException ex) when (ex.Message == "Object is disposed.") { image = MLImage.CreateFromFile(path); } Prevention
- Keep MLImage lifetime and usage in the same scope (avoid using-blocks when later access is needed)
- Never access members after Dispose; set your reference to null on dispose
- Avoid sharing MLImage instances across threads without ownership rules
- Re-create images from the source file rather than caching disposed instances
When it happens
Trigger: Accessing any property or method on an MLImage after calling Dispose() — including Width, Height, Pixels, Tag, PixelFormat, GetBGRPixels, or Save.
Common situations: Using images inside ML.NET pipelines after an owning using-block disposed them; double-dispose followed by access; caching MLImage instances across requests while disposal happens concurrently.
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
- Couldn't resize the image
- Invalid imagePixelData buffer size.
- Invalid resize mode value.
- Path has invalid image file extension.
- Pixel data is unavailable.
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/f98dae707a6ca43c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.ML.ImageAnalytics/MLImage.cs:452
{ ".jpg", SKEncodedImageFormat.Jpeg },
{ ".jpeg", SKEncodedImageFormat.Jpeg },
{ ".gif", SKEncodedImageFormat.Gif },
{ ".ico", SKEncodedImageFormat.Ico },
{ ".astc", SKEncodedImageFormat.Astc },
{ ".avif", SKEncodedImageFormat.Avif },
{ ".dng", SKEncodedImageFormat.Dng },
{ ".heif", SKEncodedImageFormat.Heif },
{ ".ktx", SKEncodedImageFormat.Ktx },
{ ".pkm", SKEncodedImageFormat.Pkm },
{ ".wbmp", SKEncodedImageFormat.Wbmp },
{ ".webp", SKEncodedImageFormat.Webp }
};
private void ThrowInvalidOperationExceptionIfDisposed()
{
if (_image is null)
{
throw new InvalidOperationException("Object is disposed.");
}
}
}
/// <summary>
/// Specifies the format of the color data for each pixel in the image.
/// </summary>
public enum MLPixelFormat
{
/// <summary>
/// The pixel format is unknown.
/// </summary>
Unknown,
/// <summary>
/// Specifies that the format is 32 bits per pixel; 8 bits each are used for the blue, green, red, and alpha components.
/// The color components are stored in blue, green, red, and alpha order
/// </summary>View on GitHub (pinned to 7b76e69cf9)