SubtitleEdit/subtitleedit · error · InvalidOperationException
End of file reached before expected
Error message
End of file reached before expected
What it means
Inside ReadAllBytesShared's read loop, Stream.Read returned 0 while count was still positive, meaning the file shrank or was concurrently truncated between the initial Length query and the reads. The buffer cannot be filled to the expected length, so the read is aborted rather than returning partial data.
Source
Thrown at src/libse/Common/FileUtil.cs:43
public static byte[] ReadAllBytesShared(string path)
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var index = 0;
var fileLength = fs.Length;
if (fileLength > int.MaxValue)
{
throw new IOException("File too long");
}
var count = (int)fileLength;
var bytes = new byte[count];
while (count > 0)
{
var n = fs.Read(bytes, index, count);
if (n == 0)
{
throw new InvalidOperationException("End of file reached before expected");
}
index += n;
count -= n;
}
return bytes;
}
}
/// <summary>
/// Opens a binary file in read/write shared mode, reads the specified number of bytes from the file into a byte array, and then closes the file.
/// </summary>
/// <param name="path">The file to open for reading.</param>
/// <param name="bytesToRead">The number of bytes to read from the file.</param>
/// <returns>A byte array containing the specified number of bytes read from the file.</returns>
public static byte[] ReadBytesShared(string path, int bytesToRead)
{View on GitHub (pinned to 17a9f07487)
Solutions
- Open the file with FileShare.ReadWrite and snapshot it (copy) before reading when concurrent writers are expected.
- Retry the read once after a short delay if a partial-read is plausible.
- For growing files, use ReadBytesShared with the known prefix length instead of the full Length.
- Handle IOException and report which byte range could not be read.
Example fix
// before
var n = fs.Read(bytes, index, count);
if (n == 0) throw new InvalidOperationException("End of file reached before expected");
// after
var n = fs.Read(bytes, index, count);
if (n == 0)
{
Array.Resize(ref bytes, index);
break; // return what was read, or surface a partial-result exception with the index Defensive patterns
Strategy: retry
Validate before calling
var info = new FileInfo(path);
if (info.Length > int.MaxValue) throw new IOException("File too long");
// optional: copy to a local snapshot before reading when a writer may truncate Try / catch
try { bytes = FileUtil.ReadAllBytesShared(path); }
catch (InvalidOperationException ex) when (ex.Message.Contains("End of file")) { /* retry once or snapshot */ } Prevention
- Snapshot files that may be concurrently truncated.
- Open with FileShare.ReadWrite to coexist with writers.
When it happens
Trigger: Another process truncates/overwrites the file mid-read; the file is on a network share that drops content; sparse file whose reported length exceeds actual data; race with a writer that did not use FileShare.ReadWrite correctly.
Common situations: Reading a log file while it is being rotated; tailing a capture file still being written by a recorder; antivirus/quarantine removing bytes during read; virtualized/network filesystem inconsistencies.
Related errors
- Too many bytes for CCData!
- Color '{colorName}' not found in SKColors.
- MXF KLV packet - lenght bytes > 8
- Translate engine '{options.TranslateEngine}' is not supporte
- Unknown {kind} language '{requested}' for this translate eng
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/9126cd3b84e40f5a.
Report an issue: GitHub.