{"record":{"id":"f6000bba195d1a52","repo":"tui-cs/Terminal.Gui","slug":"the-source-stream-must-be-seekable-canseek-proper","errorCode":null,"errorMessage":"The source stream must be seekable (CanSeek property)","messagePattern":"The source stream must be seekable \\(CanSeek property\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Terminal.Gui/Views/HexView.cs","lineNumber":320,"sourceCode":"    public void DiscardEdits () => _edits = new SortedDictionary<long, byte> ();\n\n    private Stream? _source;\n\n    /// <summary>\n    ///     Sets or gets the <see cref=\"Stream\"/> the <see cref=\"HexView\"/> is operating on; the stream must support\n    ///     seeking ( <see cref=\"Stream.CanSeek\"/> == true).\n    /// </summary>\n    /// <value>The source.</value>\n    public Stream? Source\n    {\n        get => _source;\n        set\n        {\n            ArgumentNullException.ThrowIfNull (value);\n\n            if (!value.CanSeek)\n            {\n                throw new ArgumentException (@\"The source stream must be seekable (CanSeek property)\");\n            }\n\n            DiscardEdits ();\n            _source = value;\n            SetBytesPerLine ();\n\n            if (Address > _source.Length)\n            {\n                Address = 0;\n            }\n\n            SetNeedsLayout ();\n            SetNeedsDraw ();\n        }\n    }\n\n    /// <summary>The bytes length per line.</summary>\n    public int BytesPerLine","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/tui-cs/Terminal.Gui/blob/2e47b11478db083499917f2ad27c34d30efb0df1/Terminal.Gui/Views/HexView.cs#L302-L338","documentation":"Thrown by the HexView.Source setter when the supplied Stream has CanSeek == false. HexView must seek arbitrarily through the byte source to render any address, apply edits, and navigate, so a non-seekable stream (e.g. a network pipe or unbuffered console input) cannot back the view. The check is a hard precondition in the setter, before any state is mutated.","triggerScenarios":"Assigning HexView.Source to a Stream whose CanSeek is false, such as a NetworkStream, an unbuffered Console.OpenStandardInput(), a PipeReader-as-stream, or a DeflateStream/GZipStream read stream. Also happens when wrapping a stream that loses seekability after construction.","commonSituations":"Loading bytes directly from a socket or HTTP response without buffering first; using a forward-only crypto/decoder stream; unit tests feeding a fake stream that forgets to override CanSeek to true.","solutions":["Buffer the source into a MemoryStream first: var ms = new MemoryStream(); source.CopyTo(ms); ms.Position = 0; hexView.Source = ms;","If the data is file-backed, open with File.OpenRead which is always seekable.","Subclass the stream and override CanSeek => true only if you genuinely implement Position/Seek/Length.","Pre-validate stream.CanSeek before assigning to Source and surface a user-facing message instead of letting the library throw."],"exampleFix":"// before\nusing var netStream = httpClient.GetStreamAsync(url).Result;\nhexView.Source = netStream; // throws 160\n\n// after\nusing var netStream = httpClient.GetStreamAsync(url).Result;\nusing var ms = new MemoryStream();\nnetStream.CopyTo(ms);\nms.Position = 0;\nhexView.Source = ms;","handlingStrategy":"validation","validationCode":"if (stream is null || !stream.CanSeek)\n{\n    // buffer or reject before assigning\n    using var ms = new MemoryStream();\n    stream?.CopyTo(ms);\n    ms.Position = 0;\n    hexView.Source = ms;\n    return;\n}\nhexView.Source = stream;","typeGuard":"static bool IsUsableForHexView(Stream? s) => s is { CanSeek: true };","tryCatchPattern":null,"preventionTips":["Always buffer network/pipe streams into a MemoryStream before assigning to HexView.Source.","Prefer File.OpenRead for file sources — it is always seekable.","In test fakes, override CanSeek to return true only when you implement Seek/Position/Length."],"tags":["hexview","stream","validation","precondition"],"backgroundTag":null,"analyzedSha":"2e47b11478db083499917f2ad27c34d30efb0df1","analyzedAt":"2026-08-13T19:20:08.826Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}