EllanJiang/GameFramework · error · GameFrameworkException

Read-only version list has been parsed.

Error message

Read-only version list has been parsed.

What it means

GameFramework's ResourceChecker throws this when the read-only version list load-success callback fires but m_ReadOnlyVersionListReady is already true, meaning the version list was already parsed. It guards against the async resource-loading pipeline invoking the success handler twice (e.g. duplicate events or a re-entrant check), which would corrupt check state by parsing the list a second time.

Solutions

  1. Ensure the read-only version list load task fires its success callback exactly once per request
  2. Verify your IResourceHelper/LoadBytes implementation does not invoke both success and retry-success paths
  3. Reset the ResourceChecker state (or recreate it) before starting a new resource check
  4. Check for duplicate event subscriptions to the resource manager's load events

Example fix

// before: helper may invoke onSuccess twice
helper.LoadBytes(uri, onSuccess, onFailure);
// after: guard with a local latch in the helper
bool completed = false;
void OnLoaded(byte[] bytes) { if (completed) return; completed = true; onSuccess(bytes); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (checker == null) throw new InvalidOperationException("Checker not initialized");

Try / catch

try { checker.CheckResources(); }
catch (GameFrameworkException ex) when (ex.Message.Contains("has been parsed")) { Log.Warning("Duplicate version list event ignored"); }

Prevention

When it happens

Trigger: OnLoadReadOnlyVersionListSuccess is invoked a second time after the version list has already been successfully parsed (m_ReadOnlyVersionListReady == true). Typically caused by duplicate load-success events from the resource helper or starting a new check without resetting the checker.

Common situations: Subscribing the same callback to two load tasks; a custom resource load helper that fires success more than once for one request; re-running CheckResources on a checker whose ready flags were never reset.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

                {
                    if (memoryStream != null)
                    {
                        memoryStream.Dispose();
                        memoryStream = null;
                    }
                }
            }

            private void OnLoadUpdatableVersionListFailure(string fileUri, string errorMessage, object userData)
            {
                throw new GameFrameworkException(Utility.Text.Format("Updatable version list '{0}' is invalid, error message is '{1}'.", fileUri, string.IsNullOrEmpty(errorMessage) ? "<Empty>" : errorMessage));
            }

            private void OnLoadReadOnlyVersionListSuccess(string fileUri, byte[] bytes, float duration, object userData)
            {
                if (m_ReadOnlyVersionListReady)
                {
                    throw new GameFrameworkException("Read-only version list has been parsed.");
                }

                MemoryStream memoryStream = null;
                try
                {
                    memoryStream = new MemoryStream(bytes, false);
                    LocalVersionList versionList = m_ResourceManager.m_ReadOnlyVersionListSerializer.Deserialize(memoryStream);
                    if (!versionList.IsValid)
                    {
                        throw new GameFrameworkException("Deserialize read-only version list failure.");
                    }

                    LocalVersionList.Resource[] resources = versionList.GetResources();
                    LocalVersionList.FileSystem[] fileSystems = versionList.GetFileSystems();

                    foreach (LocalVersionList.FileSystem fileSystem in fileSystems)
                    {
                        int[] resourceIndexes = fileSystem.GetResourceIndexes();

View on GitHub (pinned to d0c010b051)