EllanJiang/GameFramework · error · GameFrameworkException
appendErrorMessage
Error message
appendErrorMessage
What it means
When a UI form fails to load and there is no OpenUIFormFailure event subscriber, UIManager has nowhere to report the failure and rethrows the accumulated error message (appendErrorMessage, built from the resource error plus a hint to check the failure event) as a GameFrameworkException. The message text is literally the underlying appendErrorMessage string.
Solutions
- Subscribe to UIComponent.OpenUIFormFailure to receive failures gracefully
- Verify the uiFormAssetName matches an asset in the resource list; rebuild resource collection if it was added recently
- Read the appendErrorMessage text — it contains the underlying LoadResourceStatus error
- In non-Unity/framework-only tests, attach OpenUIFormFailureEventHandler before opening forms
Example fix
// before
m_UIComponent.OpenUIForm("Assets/UI/BagForm", "Default", userData); // throws on missing asset
// after
m_UIComponent.OpenUIFormFailure += (s, e) =>
Log.Error("Open form failed: {0}, {1}", e.UIFormAssetName, e.ErrorMessage);
m_UIComponent.OpenUIForm("Assets/UI/BagForm", "Default", userData); Defensive patterns
Strategy: try-catch
Validate before calling
if (string.IsNullOrEmpty(assetName) || !m_ResourceComponent.HasAsset(assetName))
{
Log.Error("UI form asset missing: {0}", assetName);
return;
} Try / catch
m_UIComponent.OpenUIFormFailure += (sender, e) =>
{
Log.Error("OpenUIForm failed: {0} ({1})", e.UIFormAssetName, e.ErrorMessage);
};
// and wrap opens: try { m_UIComponent.OpenUIForm(...); } catch (GameFrameworkException ex) { Log.Error(ex.Message); } Prevention
- Always register an OpenUIFormFailure handler before opening forms
- Rebuild resource collection/bundles after adding new UI prefabs
- Validate form asset names at build time with a manifest check
- Log appendErrorMessage text to find the root resource error
When it happens
Trigger: OpenUIForm's async load failed (missing/invalid asset, resource error) AND no handler is registered on UIComponent.OpenUIFormFailure (UnityEvent), so the exception propagates out of the load callback.
Common situations: Typo in UIForm asset name or form not packed into resources; running in editor without rebuilding the asset bundle/resource collection; forgetting to hook OpenUIFormFailure in game code so failures crash instead of being handled.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Open UI form info is invalid.
- Entity ' ' is already being loaded.
- Load resource agent helper is invalid.
- Resource helper is invalid.
- Resource loader is invalid.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/1d3ff920b2dab125.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/UI/UIManager.cs:1024
}
if (m_UIFormsToReleaseOnLoad.Contains(openUIFormInfo.SerialId))
{
m_UIFormsToReleaseOnLoad.Remove(openUIFormInfo.SerialId);
return;
}
m_UIFormsBeingLoaded.Remove(openUIFormInfo.SerialId);
string appendErrorMessage = Utility.Text.Format("Load UI form failure, asset name '{0}', status '{1}', error message '{2}'.", uiFormAssetName, status, errorMessage);
if (m_OpenUIFormFailureEventHandler != null)
{
OpenUIFormFailureEventArgs openUIFormFailureEventArgs = OpenUIFormFailureEventArgs.Create(openUIFormInfo.SerialId, uiFormAssetName, openUIFormInfo.UIGroup.Name, openUIFormInfo.PauseCoveredUIForm, appendErrorMessage, openUIFormInfo.UserData);
m_OpenUIFormFailureEventHandler(this, openUIFormFailureEventArgs);
ReferencePool.Release(openUIFormFailureEventArgs);
return;
}
throw new GameFrameworkException(appendErrorMessage);
}
private void LoadAssetUpdateCallback(string uiFormAssetName, float progress, object userData)
{
OpenUIFormInfo openUIFormInfo = (OpenUIFormInfo)userData;
if (openUIFormInfo == null)
{
throw new GameFrameworkException("Open UI form info is invalid.");
}
if (m_OpenUIFormUpdateEventHandler != null)
{
OpenUIFormUpdateEventArgs openUIFormUpdateEventArgs = OpenUIFormUpdateEventArgs.Create(openUIFormInfo.SerialId, uiFormAssetName, openUIFormInfo.UIGroup.Name, openUIFormInfo.PauseCoveredUIForm, progress, openUIFormInfo.UserData);
m_OpenUIFormUpdateEventHandler(this, openUIFormUpdateEventArgs);
ReferencePool.Release(openUIFormUpdateEventArgs);
}
}
View on GitHub (pinned to d0c010b051)