{"record":{"id":"21796099456ab603","repo":"SubtitleEdit/subtitleedit","slug":"stream-is-too-small","errorCode":null,"errorMessage":"Stream is too small","messagePattern":"Stream is too small","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ui/Logic/Media/WaveToVisualizer2.cs","lineNumber":76,"sourceCode":"    public string DataId { get; private set; }\n\n    /// <summary>\n    /// Size of sound data\n    /// </summary>\n    public uint DataChunkSize { get; private set; }\n\n    public int DataStartPosition { get; private set; }\n\n    public WaveHeader2(Stream stream)\n    {\n        stream.Position = 0;\n\n        // Read constant header\n        Span<byte> buffer = stackalloc byte[ConstantHeaderSize];\n        int bytesRead = stream.Read(buffer);\n        if (bytesRead < buffer.Length)\n        {\n            throw new ArgumentException(\"Stream is too small\");\n        }\n\n        // Parse constant header - use Span slicing to avoid array indexing\n        ChunkId = Encoding.UTF8.GetString(buffer.Slice(0, 4));\n        ChunkSize = BitConverter.ToUInt32(buffer.Slice(4));\n        Format = Encoding.UTF8.GetString(buffer.Slice(8, 4));\n        FmtId = Encoding.UTF8.GetString(buffer.Slice(12, 4));\n        FmtChunkSize = BitConverter.ToInt32(buffer.Slice(16));\n\n        // Read fmt chunk - allocate only if needed (usually 16-18 bytes, max ~40)\n        Span<byte> fmtBuffer = FmtChunkSize <= 128\n            ? stackalloc byte[FmtChunkSize]\n            : new byte[FmtChunkSize];\n        _ = stream.Read(fmtBuffer);\n\n        // Parse fmt chunk\n        AudioFormat = BitConverter.ToInt16(fmtBuffer);\n        NumberOfChannels = BitConverter.ToInt16(fmtBuffer.Slice(2));","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Logic/Media/WaveToVisualizer2.cs#L58-L94","documentation":"Thrown by the WaveHeader2 constructor when the supplied Stream does not contain at least ConstantHeaderSize (20) bytes of a RIFF/WAVE header. The reader seeks to position 0 and attempts a single Read into a 20-byte stackalloc buffer; if fewer bytes come back the stream cannot represent a valid WAV file, so parsing aborts before any header field is interpreted. This is an ArgumentException, not an end-of-stream IOException, because the precondition (a minimally-sized stream) was violated by the caller.","triggerScenarios":"Constructing new WaveHeader2(stream) where stream is empty, contains only a few bytes, points at a non-WAV file, or wraps a truncated/corrupt buffer. Also triggered when stream.Read returns a short count on the first call (e.g. a NetworkStream or CryptoStream with insufficient buffered data).","commonSituations":"Opening a .wav that is actually a text/MP3/FLAC file; a zero-byte placeholder file; a download that was cut off; passing a MemoryStream built from a non-audio byte array; reading a stream whose CanRead is true but which yields fewer bytes than Length suggests.","solutions":["Verify the file extension and magic bytes (bytes 0-3 must be 'RIFF' and 8-11 'WAVE') before constructing WaveHeader2.","Check stream.Length >= 44 (minimal WAV) before calling the constructor.","If the stream may be incomplete, read fully into a MemoryStream first so the length is authoritative.","Validate that the input is actually a PCM WAV rather than another audio container."],"exampleFix":"// before\nvar header = new WaveHeader2(fileStream);\n\n// after\nif (fileStream.Length < 44) throw new InvalidDataException(\"Not a valid WAV file: too small\");\nvar header = new WaveHeader2(fileStream);","handlingStrategy":"validation","validationCode":"// before constructing WaveHeader2\nif (stream == null) throw new ArgumentNullException(nameof(stream));\nif (!stream.CanRead) throw new ArgumentException(\"Stream is not readable\");\nif (stream.Length < 44) throw new InvalidDataException(\"Stream is too small to be a WAV file\");\nstream.Position = 0;\nSpan<byte> magic = stackalloc byte[12];\nstream.Read(magic);\nstream.Position = 0;\nif (Encoding.ASCII.GetString(magic.Slice(0,4)) != \"RIFF\" || Encoding.ASCII.GetString(magic.Slice(8,4)) != \"WAVE\")\n    throw new InvalidDataException(\"Not a RIFF/WAVE stream\");","typeGuard":"static bool IsValidWavStream(Stream s) => s != null && s.CanRead && s.Length >= 44;","tryCatchPattern":"try { var header = new WaveHeader2(stream); }\ncatch (ArgumentException ex) when (ex.Message == \"Stream is too small\") { /* prompt user for a valid WAV */ }","preventionTips":["Always check stream.Length >= 44 before parsing a WAV header.","Validate 'RIFF'/'WAVE' magic bytes before handing the stream to WaveHeader2.","Read remote/network streams fully into a MemoryStream first so Length is reliable.","Filter file pickers to .wav and re-validate by magic bytes."],"tags":["wav","audio","validation","stream","argument"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}