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

  1. Subscribe to UIComponent.OpenUIFormFailure to receive failures gracefully
  2. Verify the uiFormAssetName matches an asset in the resource list; rebuild resource collection if it was added recently
  3. Read the appendErrorMessage text — it contains the underlying LoadResourceStatus error
  4. 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

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


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)