EllanJiang/GameFramework · critical · GameFrameworkException

Read-write path is invalid.

Error message

Read-write path is invalid.

What it means

CheckResources also requires the read-write path (ReadWritePath, where downloaded/updated resources are stored) to be non-empty, because the remote version list is loaded from it. If m_ReadWritePath is null or empty the framework throws this GameFrameworkException.

Solutions

  1. Assign resourceComponent.ReadWritePath = Application.persistentDataPath (or equivalent writable dir) before calling CheckResources.
  2. Ensure FileHelper/MakeSureDirectoryExists runs so the writable path is valid on the target platform.
  3. Reorder bootstrap code so path assignment happens before CheckResources.

Example fix

// before
m_ResourceComponent.CheckResources(); // ReadWritePath not set

// after
m_ResourceComponent.ReadWritePath = Application.persistentDataPath;
m_ResourceComponent.CheckResources();
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(m_ResourceComponent.ReadWritePath))
    m_ResourceComponent.ReadWritePath = Application.persistentDataPath;
if (!Directory.Exists(m_ResourceComponent.ReadWritePath))
    Directory.CreateDirectory(m_ResourceComponent.ReadWritePath);

Try / catch

try { m_ResourceComponent.CheckResources(); }
catch (GameFrameworkException ex) when (ex.Message == "Read-write path is invalid.")
{
    Debug.LogError("ReadWritePath not set; point it at persistent data before checking resources.");
}

Prevention

When it happens

Trigger: Calling CheckResources when resourceComponent.ReadWritePath (or ResourceManager.m_ReadWritePath) is null or string.Empty — e.g. the writable-path initialization step was skipped or assigned after CheckResources.

Common situations: Not setting ReadWritePath to a persistent-data location (Application.persistentDataPath) before starting a resource update; calling CheckResources from a custom manager that bypasses the component's initialization flow.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

            /// 检查资源。
            /// </summary>
            /// <param name="currentVariant">当前使用的变体。</param>
            /// <param name="ignoreOtherVariant">是否忽略处理其它变体的资源,若不忽略,将会移除其它变体的资源。</param>
            public void CheckResources(string currentVariant, bool ignoreOtherVariant)
            {
                if (m_ResourceManager.m_ResourceHelper == null)
                {
                    throw new GameFrameworkException("Resource helper is invalid.");
                }

                if (string.IsNullOrEmpty(m_ResourceManager.m_ReadOnlyPath))
                {
                    throw new GameFrameworkException("Read-only path is invalid.");
                }

                if (string.IsNullOrEmpty(m_ResourceManager.m_ReadWritePath))
                {
                    throw new GameFrameworkException("Read-write path is invalid.");
                }

                m_CurrentVariant = currentVariant;
                m_IgnoreOtherVariant = ignoreOtherVariant;
                m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadWritePath, RemoteVersionListFileName)), new LoadBytesCallbacks(OnLoadUpdatableVersionListSuccess, OnLoadUpdatableVersionListFailure), null);
                m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadOnlyPath, LocalVersionListFileName)), new LoadBytesCallbacks(OnLoadReadOnlyVersionListSuccess, OnLoadReadOnlyVersionListFailure), null);
                m_ResourceManager.m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(m_ResourceManager.m_ReadWritePath, LocalVersionListFileName)), new LoadBytesCallbacks(OnLoadReadWriteVersionListSuccess, OnLoadReadWriteVersionListFailure), null);
            }

            private void SetCachedFileSystemName(ResourceName resourceName, string fileSystemName)
            {
                GetOrAddCheckInfo(resourceName).SetCachedFileSystemName(fileSystemName);
            }

            private void SetVersionInfo(ResourceName resourceName, LoadType loadType, int length, int hashCode, int compressedLength, int compressedHashCode)
            {
                GetOrAddCheckInfo(resourceName).SetVersionInfo(loadType, length, hashCode, compressedLength, compressedHashCode);
            }

View on GitHub (pinned to d0c010b051)