EllanJiang/GameFramework · error · GameFrameworkException

Save as file ' ' to ' ' from file system ' ' error.

Error message

Save as file '{0}' to '{1}' from file system '{2}' error.

What it means

During RefreshCheckInfoStatus, resources stored in a read-write binary file system that must be moved back to disk are extracted with IFileSystem.SaveAsFile. When SaveAsFile returns false the framework cannot materialize the resource file at resourcePath and throws this formatted GameFrameworkException naming the resource, target path and file system full path.

Solutions

  1. Delete stale files with the same name in ReadWritePath (or clear ReadWritePath) and re-run the resource update so SaveAsFile has no conflicting target.
  2. Regenerate/repair the read-write file system: if m_ReadWriteFileSystems data is corrupted, remove the read-write directory and redownload resources.
  3. Check free disk space and write permissions for ReadWritePath on the device.
  4. Verify the read-write version list and file system were produced by the same resource build.

Example fix

// before (stale file blocks SaveAsFile)
m_ResourceComponent.CheckResources();

// after: clean conflicting stale files first
string stalePath = Utility.Path.GetRegularPath(Path.Combine(readWritePath, resourceFullName));
if (File.Exists(stalePath)) File.Delete(stalePath);
m_ResourceComponent.CheckResources();
Defensive patterns

Strategy: try-catch

Validate before calling

string target = Utility.Path.GetRegularPath(Path.Combine(readWritePath, resourceFullName));
if (File.Exists(target)) File.Delete(target); // remove stale conflict before check
long freeSpace = new DriveInfo(Path.GetPathRoot(readWritePath)).AvailableFreeSpace;
if (freeSpace < 64L * 1024 * 1024) Debug.LogWarning("Low disk space before resource check");

Try / catch

try { m_ResourceComponent.CheckResources(); }
catch (GameFrameworkException ex) when (ex.Message.StartsWith("Save as file"))
{
    Debug.LogError($"Move-to-disk failed, clearing read-write area: {ex.Message}");
    if (Directory.Exists(readWritePath)) Directory.Delete(readWritePath, true);
    // restart the update flow
}

Prevention

When it happens

Trigger: RefreshCheckInfoStatus processes a CheckInfo with NeedMoveToDisk=true and the underlying file system's SaveAsFile fails — typically because the destination disk file already exists or the file system lacks the resource entry, or disk I/O fails.

Common situations: Leftover stale files in ReadWritePath from a previous build/version; corrupted read-write file system (.dat) after a crashed update; running out of disk space on device; mismatched version lists after upgrading the resource pipeline.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

Thrown at GameFramework/Resource/ResourceManager.ResourceChecker.cs:154

                    CheckInfo ci = checkInfo.Value;
                    ci.RefreshStatus(m_CurrentVariant, m_IgnoreOtherVariant);
                    if (ci.Status == CheckInfo.CheckStatus.StorageInReadOnly)
                    {
                        m_ResourceManager.m_ResourceInfos.Add(ci.ResourceName, new ResourceInfo(ci.ResourceName, ci.FileSystemName, ci.LoadType, ci.Length, ci.HashCode, ci.CompressedLength, true, true));
                    }
                    else if (ci.Status == CheckInfo.CheckStatus.StorageInReadWrite)
                    {
                        if (ci.NeedMoveToDisk || ci.NeedMoveToFileSystem)
                        {
                            movedCount++;
                            string resourceFullName = ci.ResourceName.FullName;
                            string resourcePath = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.m_ReadWritePath, resourceFullName));
                            if (ci.NeedMoveToDisk)
                            {
                                IFileSystem fileSystem = m_ResourceManager.GetFileSystem(ci.ReadWriteFileSystemName, false);
                                if (!fileSystem.SaveAsFile(resourceFullName, resourcePath))
                                {
                                    throw new GameFrameworkException(Utility.Text.Format("Save as file '{0}' to '{1}' from file system '{2}' error.", resourceFullName, resourcePath, fileSystem.FullPath));
                                }

                                fileSystem.DeleteFile(resourceFullName);
                            }

                            if (ci.NeedMoveToFileSystem)
                            {
                                IFileSystem fileSystem = m_ResourceManager.GetFileSystem(ci.FileSystemName, false);
                                if (!fileSystem.WriteFile(resourceFullName, resourcePath))
                                {
                                    throw new GameFrameworkException(Utility.Text.Format("Write resource '{0}' to file system '{1}' error.", resourceFullName, fileSystem.FullPath));
                                }

                                if (File.Exists(resourcePath))
                                {
                                    File.Delete(resourcePath);
                                }
                            }

View on GitHub (pinned to d0c010b051)