EllanJiang/GameFramework · error · GameFrameworkException
Stream is not writable.
Error message
Stream is not writable.
What it means
FileSystem.ReadFile throws this when the destination stream exists but its CanWrite property is false. Reading a file copies bytes into the supplied stream, so the stream must be writable. Read-only streams (e.g. a stream opened from a file with FileAccess.Read, or Stream.Null) are rejected.
Solutions
- Pass a writable stream such as new MemoryStream() or a FileStream opened with FileAccess.Write/ReadWrite.
- Check stream.CanWrite before calling ReadFile.
- If you only need the bytes, use the byte[]-oriented overloads (ReadFileSegment) instead of the stream overload.
Example fix
// before
using (var stream = File.OpenRead(path))
{
fs.ReadFile(name, stream); // throws: CanWrite == false
}
// after
using (var stream = new MemoryStream())
{
fs.ReadFile(name, stream);
} Defensive patterns
Strategy: validation
Validate before calling
if (stream == null || !stream.CanWrite)
throw new ArgumentException("Stream must be writable to receive file contents", nameof(stream));
int read = fs.ReadFile(name, stream); Type guard
static bool IsWritableStream(Stream stream) => stream != null && stream.CanWrite;
Try / catch
try
{
int read = fs.ReadFile(name, stream);
}
catch (GameFrameworkException ex) when (ex.Message == "Stream is not writable.")
{
// swap in a MemoryStream / writable FileStream
} Prevention
- Remember ReadFile's stream is an output buffer: it must be writable.
- Don't reuse read-only input streams (File.OpenRead, LoadFileSystem sources) as destinations.
- Prefer new MemoryStream() as the standard destination.
When it happens
Trigger: Calling ReadFile with a stream obtained from File.OpenRead, a read-only FileStream, Stream.Null, or any Stream whose CanWrite returns false.
Common situations: Reusing the same read-only stream that was previously used to feed FileSystem.LoadFileSystem; wrapping a read-only underlying file; passing a readonly MemoryStream created over a fixed buffer (CanWrite is actually true there, so usually it is a read-only FileStream).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Stream is not readable.
- Offset is invalid.
- Length is invalid.
- Max file count is invalid.
- Max block count is invalid.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/74f614169a710a17.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/FileSystem/FileSystem.cs:469
{
if (m_Access != FileSystemAccess.Read && m_Access != FileSystemAccess.ReadWrite)
{
throw new GameFrameworkException("File system is not readable.");
}
if (string.IsNullOrEmpty(name))
{
throw new GameFrameworkException("Name is invalid.");
}
if (stream == null)
{
throw new GameFrameworkException("Stream is invalid.");
}
if (!stream.CanWrite)
{
throw new GameFrameworkException("Stream is not writable.");
}
FileInfo fileInfo = GetFileInfo(name);
if (!fileInfo.IsValid)
{
return 0;
}
int length = fileInfo.Length;
if (length > 0)
{
m_Stream.Position = fileInfo.Offset;
return m_Stream.Read(stream, length);
}
return 0;
}
View on GitHub (pinned to d0c010b051)