EllanJiang/GameFramework · error · GameFrameworkException

Updatable version list

Error message

Updatable version list '{0}' is invalid, error message is '{1}'.

What it means

When the ResourceHelper fails to load the remote (updatable) version list bytes, OnLoadUpdatableVersionListFailure converts that load failure into a GameFrameworkException naming the requested fileUri and the helper's error message (or '<Empty>' if none). Unlike the read-only/read-write list handlers, a failed remote list load is fatal — the update cannot proceed without it.

Solutions

  1. Check the fileUri in the message: verify the remote version list exists at that exact URL/path (fix server file name/version directory).
  2. Test network connectivity and retry the update when the device is online.
  3. Inspect errorMessage (or <Empty>) from your DefaultResourceHelper log to see the underlying cause (404, DNS, timeout).
  4. Implement retry logic around UpdateResourceAsync for transient network failures.

Example fix

// before
m_ResourceComponent.UpdateResourceAsync(); // no retry on flaky network

// after
IEnumerator UpdateWithRetry(int maxRetries = 3)
{
    for (int i = 0; i < maxRetries; i++)
    {
        bool failed = false;
        // hook ResourceUpdateFailure / failure log to set failed=true
        m_ResourceComponent.UpdateResourceAsync();
        yield return new WaitUntil(() => done || (failed = FailureReported));
        if (!failed) yield break;
        yield return new WaitForSeconds(2f * (i + 1));
    }
}
Defensive patterns

Strategy: retry

Validate before calling

UnityWebRequest head = UnityWebRequest.Head(versionListUrl);
yield return head.SendWebRequest();
bool reachable = head.result == UnityWebRequest.Result.Success
    && (long)head.responseCode == 200;

Try / catch

try { m_ResourceComponent.UpdateResourceAsync(); }
catch (GameFrameworkException ex) when (ex.Message.StartsWith("Updatable version list"))
{
    Debug.LogError($"Remote version list load failed: {ex.Message}");
    // schedule a retry with backoff, or fall back to bundled resources
}

Prevention

When it happens

Trigger: The ResourceHelper's LoadBytes fails for the remote version list file at Path.Combine(ReadWritePath or remote URL, 'GameFrameworkList.dat') — missing file, unreachable server, network timeout, permission error on ReadWritePath.

Common situations: First launch before any update where the remote URL is wrong or CDN is down; device offline or on a captive portal; the version list was deleted/misnamed on the server; version list expected locally in ReadWritePath but never downloaded yet.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

                    {
                        throw;
                    }

                    throw new GameFrameworkException(Utility.Text.Format("Parse updatable version list exception '{0}'.", exception), exception);
                }
                finally
                {
                    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.");
                    }

View on GitHub (pinned to d0c010b051)