{"record":{"id":"293e0adabcea1d49","repo":"dotnet/wpf","slug":"sr-packagingwriteabledelegategavenullstream","errorCode":null,"errorMessage":"SR.PackagingWriteableDelegateGaveNullStream","messagePattern":"SR\\.PackagingWriteableDelegateGaveNullStream","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/WriteableOnDemandStream.cs","lineNumber":287,"sourceCode":"    /// Ensures either the active stream is our writeable stream or uses the\n    /// factory delegate to get one and assign it as the active stream.\n    /// </summary>\n    /// <exception cref=\"System.IO.IOException\" />\n    /// <exception cref=\"System.NotSupportedException\" />\n    private void EnsureWritable()\n    {\n        if (!_wantedWrite)\n        {\n            throw new NotSupportedException(\n                SR.PackagingWriteNotSupported);\n        }\n\n        if (!_isActiveWriteable)\n        {\n            Stream writer = _writeableStreamFactory(_mode, _access);\n            if (writer == null)\n            {\n                throw new IOException(\n                    SR.PackagingWriteableDelegateGaveNullStream);\n            }\n\n            if (writer.Equals(this))\n            {\n                throw new IOException(\n                    SR.PackagingCircularReference);\n            }\n\n            writer.Position = _active.Position;\n\n            _active = writer;\n            _isActiveWriteable = true;\n        }\n    }\n    #endregion Private Methods\n\n    #region Private Fields","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/WriteableOnDemandStream.cs#L269-L305","documentation":"WriteableOnDemandStream.EnsureWritable invokes the _writeableStreamFactory delegate to obtain the real writeable stream; if the delegate returns null the lazy stream has no backing writer, so IOException(PackagingWriteableDelegateGaveNullStream) is thrown.","triggerScenarios":"First Write or SetLength call on an on-demand stream that is not yet actively writeable, where the registered WriteableStreamFactory callback returns null instead of a Stream.","commonSituations":"Deferred-save XPS scenarios where the factory's part creation failed silently (package disposed, part missing) and the error path returned null rather than throwing.","solutions":["Ensure the writeable stream factory always returns a non-null Stream or throws an exception with context.","Check that the package/part backing the stream is still open and writeable when the factory executes.","Validate writeability (part-level checks) before beginning the deferred write flow."],"exampleFix":"// before\nStream Factory(FileMode m, FileAccess a) => _part?.GetStream(m, a); // null when _part is null\n// after\nStream Factory(FileMode m, FileAccess a)\n{\n    if (_part == null) throw new IOException(\"Backing part unavailable for write\");\n    return _part.GetStream(m, a);\n}","handlingStrategy":"validation","validationCode":"if (backingPart == null || !backingPart.FileOpenAccess.HasFlag(FileAccess.Write))\n    throw new IOException(\"Backing part unavailable or not writeable for on-demand stream.\");","typeGuard":"bool CanProvideWritableStream(Func<FileMode, FileAccess, Stream> f)\n{ try { return f?.Invoke(FileMode.OpenOrCreate, FileAccess.Write) != null; } catch { return false; } }","tryCatchPattern":"try { stream.Write(data, 0, data.Length); }\ncatch (IOException ex) when (ex.Message.Contains(\"GaveNullStream\"))\n{ Log.Error(\"Stream factory returned null\", ex); }","preventionTips":["Factory must throw, never return null.","Validate backing part lifetime before deferred writes.","Test the factory after package close/dispose."],"tags":["wpf","packaging","null-reference","io"],"backgroundTag":"null-argument","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}