EllanJiang/GameFramework · critical · GameFrameworkException
Read-only path is invalid.
Error message
Read-only path is invalid.
What it means
CheckResources verifies that the ResourceManager's read-only path (ReadOnlyPath, where bundled/package resources live) is a non-empty string before loading the local version list. An empty or null path means the framework cannot locate read-only resources, so it throws this GameFrameworkException.
Solutions
- Set resourceComponent.ReadOnlyPath (usually Application.streamingAssetsPath or a platform-specific path) before calling CheckResources.
- Verify the GameFramework ResourceComponent inspector has a valid ReadOnlyPath configured for the active platform.
- Add a null/empty assertion on ReadOnlyPath in your own bootstrap prior to invoking CheckResources.
Example fix
// before m_ResourceComponent.ReadOnlyPath = string.Empty; m_ResourceComponent.CheckResources(); // throws // after #if UNITY_ANDROID m_ResourceComponent.ReadOnlyPath = Application.streamingAssetsPath; #else m_ResourceComponent.ReadOnlyPath = Utility.Path.GetRegularPath(Application.dataPath); #endif m_ResourceComponent.CheckResources();
Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(m_ResourceComponent.ReadOnlyPath))
m_ResourceComponent.ReadOnlyPath = Application.streamingAssetsPath;
if (string.IsNullOrEmpty(m_ResourceComponent.ReadOnlyPath))
throw new InvalidOperationException("ReadOnlyPath must be configured before CheckResources"); Try / catch
try { m_ResourceComponent.CheckResources(); }
catch (GameFrameworkException ex) when (ex.Message == "Read-only path is invalid.")
{
Debug.LogError("ReadOnlyPath not set; configure the ResourceComponent for this platform.");
} Prevention
- Set ReadOnlyPath per platform in a dedicated bootstrap method before any resource call.
- Verify ResourceComponent inspector values in a CI/editor smoke test.
- Never clear ReadOnlyPath at runtime.
When it happens
Trigger: Calling CheckResources when resourceComponent.ReadOnlyPath (or ResourceManager.m_ReadOnlyPath) was never assigned or was set to string.Empty, typically because the ResReaderMode/ReadOnlyPath config was not initialized before the check.
Common situations: Skipping the ResourceComponent inspector configuration; wiping ReadOnlyPath in a custom editor script; initializing resources in a stripped scene where the ResourceComponent defaults were not applied.
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
- Read-write path is invalid.
- Read-only path is invalid.
- Config helper is invalid.
- Config name ' ' is not exist.
- Config name is invalid.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/cbebab91ff1e00f2.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/Resource/ResourceManager.ResourceChecker.cs:73
{
m_CheckInfos.Clear();
}
/// <summary>
/// 检查资源。
/// </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);
}View on GitHub (pinned to d0c010b051)