EllanJiang/GameFramework · error · GameFrameworkException

File system is not writable.

Error message

File system is not writable.

What it means

WriteFile(string name, byte[] buffer, int startIndex, int length) throws this GameFrameworkException when the file system was opened with FileSystemAccess.Read only. Writing requires the file system to have been created/opened with Write or ReadWrite access. The guard fires before any name or buffer validation.

Solutions

  1. Open the file system with FileSystemAccess.Write or FileSystemAccess.ReadWrite (e.g. via FileSystem.Create with access: FileSystemAccess.ReadWrite).
  2. If the file system is already created, check fs.Access (m_Access) before writing and route writes to a writable instance.
  3. Split usage: keep a read-only instance for shipped data and a separate ReadWrite instance for user-writable data.

Example fix

// before
var fs = FileSystem.Create(fullPath, FileSystemAccess.Read, ...);
fs.WriteFile(name, buffer, 0, buffer.Length); // throws
// after
var fs = FileSystem.Create(fullPath, FileSystemAccess.ReadWrite, ...);
fs.WriteFile(name, buffer, 0, buffer.Length);
Defensive patterns

Strategy: validation

Validate before calling

if (fs.Access != FileSystemAccess.Write && fs.Access != FileSystemAccess.ReadWrite) throw new InvalidOperationException("File system opened read-only; cannot write.");

Type guard

static bool IsWritable(FileSystem fs) => fs != null && (fs.Access == FileSystemAccess.Write || fs.Access == FileSystemAccess.ReadWrite);

Try / catch

try { fs.WriteFile(name, buffer, startIndex, length); } catch (GameFrameworkException ex) when (ex.Message == "File system is not writable.") { /* reopen with Write/ReadWrite access */ }

Prevention

When it happens

Trigger: Opening a FileSystem (FileSystem.Create / LoadFileSystem or via the helper with access parameter) with FileSystemAccess.Read, then calling any WriteFile overload. Common when the same open handle is reused for both reads and writes.

Common situations: A config or download flag opens the package read-only (e.g. shipped game data) but update code later tries to write into it; sharing one FileSystem instance between a read path and a write path; access enum changed during a refactor.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15). Data as JSON: /api/errors/81ec0a5fbf2b2d8b. Report an issue: GitHub.

Appendix: source

Thrown at GameFramework/FileSystem/FileSystem.cs:811

                throw new GameFrameworkException("Buffer is invalid.");
            }

            return WriteFile(name, buffer, startIndex, buffer.Length - startIndex);
        }

        /// <summary>
        /// 写入指定文件。
        /// </summary>
        /// <param name="name">要写入的文件名称。</param>
        /// <param name="buffer">存储写入文件内容的二进制流。</param>
        /// <param name="startIndex">存储写入文件内容的二进制流的起始位置。</param>
        /// <param name="length">存储写入文件内容的二进制流的长度。</param>
        /// <returns>是否写入指定文件成功。</returns>
        public bool WriteFile(string name, byte[] buffer, int startIndex, int length)
        {
            if (m_Access != FileSystemAccess.Write && m_Access != FileSystemAccess.ReadWrite)
            {
                throw new GameFrameworkException("File system is not writable.");
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new GameFrameworkException("Name is invalid.");
            }

            if (name.Length > byte.MaxValue)
            {
                throw new GameFrameworkException(Utility.Text.Format("Name '{0}' is too long.", name));
            }

            if (buffer == null)
            {
                throw new GameFrameworkException("Buffer is invalid.");
            }

            if (startIndex < 0 || length < 0 || startIndex + length > buffer.Length)

View on GitHub (pinned to d0c010b051)