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
- Ensure the read-only version list load task fires its success callback exactly once per request
- Verify your IResourceHelper/LoadBytes implementation does not invoke both success and retry-success paths
- Reset the ResourceChecker state (or recreate it) before starting a new resource check
- 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
- Fire exactly one success/failure callback per load request in custom helpers
- Never re-run resource checks on a checker instance that already completed without resetting it
- Deduplicate event handler subscriptions
- Add logging in the load helper to detect double completion
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
- Read-write version list has been parsed.
- Updatable version list has been parsed.
- Deserialize updatable version list failure.
- Parse updatable version list exception
- Updatable version list
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)