{"record":{"id":"7562cde2e85f4933","repo":"louthy/language-ext","slug":"invalidcastexception","errorCode":null,"errorMessage":"InvalidCastException","messagePattern":"InvalidCastException","errorType":"exception","errorClass":"InvalidCastException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Effects/IO/Resources.cs","lineNumber":52,"sourceCode":"        {\n            item.Value.Release().Run(disposeEnv);\n        }\n        return default;\n    }\n\n    public Unit DisposeU()\n    {\n        Dispose();\n        return default;\n    }\n\n    public IO<Unit> DisposeIO() =>\n        IO.lift(_ => DisposeU());\n\n    public Unit Acquire<A>(A value) where A : IDisposable\n    {\n        var obj = (object?)value;\n        if (obj is null) throw new InvalidCastException();\n        return resources.TryAdd(obj, new TrackedResourceDisposable<A>(value));\n    }\n\n    public Unit AcquireAsync<A>(A value) where A : IAsyncDisposable\n    {\n        var obj = (object?)value;\n        if (obj is null) throw new InvalidCastException();\n        return resources.TryAdd(obj, new TrackedResourceAsyncDisposable<A>(value));\n    }\n\n    public Unit Acquire<A>(A value, Func<A, IO<Unit>> release) \n    {\n        var obj = (object?)value;\n        if (obj is null) throw new InvalidCastException();\n        return resources.TryAdd(obj, new TrackedResourceWithFree<A>(value, release));\n    }\n\n    public IO<Unit> Release<A>(A value)","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Effects/IO/Resources.cs#L34-L70","documentation":"Resources.Acquire throws InvalidCastException when the IDisposable value passed in boxes to null. The code casts the generic value to object and treats null as an invalid cast rather than a null-argument problem, so passing a null reference (or Nullable<T> with no value) to Acquire produces this exception instead of ArgumentNullException.","triggerScenarios":"Calling Resources.Acquire<A>(null) where A is a reference type implementing IDisposable, or Acquire on a Nullable value type whose HasValue is false (e.g. default(Nullable<FileStream>) boxed to null).","commonSituations":"Passing an uninitialized field or a method returning null (e.g. a config lookup for a stream/connection) into resource tracking during IO bracket/using-style composition.","solutions":["Ensure the value passed to Acquire is a non-null IDisposable before calling it.","If null is a legitimate possibility, use a Match/IfNone pattern or check value is not null first.","If you own the caller, throw a clearer ArgumentNullException at your boundary instead of letting this surface."],"exampleFix":"// before\nresources.Acquire(GetStream()); // GetStream() may return null\n// after\nvar stream = GetStream() ?? throw new InvalidOperationException(\"stream not configured\");\nresources.Acquire(stream);","handlingStrategy":"type-guard","validationCode":"if (value is null) throw new ArgumentNullException(nameof(value));","typeGuard":"static bool IsUsable<A>(A v) where A : IDisposable => v is not null;","tryCatchPattern":"try { resources.Acquire(stream); } catch (InvalidCastException) { /* null resource passed */ }","preventionTips":["Null-check resources at acquisition boundaries","Prefer Option<A> over nullable references when producing resources","Never rely on default values for IDisposable fields"],"tags":["null","csharp","resources","io"],"backgroundTag":"null-argument","analyzedSha":"2f0e3628242889774d4141960a35671a0280051f","analyzedAt":"2026-09-15T03:31:55.716Z","contentChangedAt":"2026-09-15T03:31:55.716Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}