EllanJiang/GameFramework · error · GameFrameworkException

appendErrorMessage

Error message

appendErrorMessage

What it means

In LoadAssetOrBinaryFailureCallback, when neither an asset nor binary load path succeeded, DataProvider throws GameFrameworkException with appendErrorMessage — the accumulated error message from the failed load attempt. The message text is not a fixed string; it carries the underlying load failure details.

Solutions

  1. Read appendErrorMessage to find the underlying load failure (missing asset, IO error, etc.).
  2. Fix the asset name/path or rebuild resource packages so the data asset exists.
  3. Ensure the resource system can locate the asset (check SearchPaths, AssetBundle manifests).
  4. Subscribe ReadDataFailureEventHandler so load failures surface as events instead of exceptions.

Example fix

// before
dataTableComponent.ReadData("MissingTable"); // throws on load failure
// after
m_DataTableComponent.ReadDataFailure += (sender, e) =>
{
    Log.Error("Data load failed: {0} - {1}", e.DataAssetName, e.ErrorMessage);
};
m_DataTableComponent.ReadData("MyDataTable");
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check asset presence before loading
if (resourceComponent.HasAsset(dataAssetName))
{
    dataProvider.ReadData(dataAssetName);
}
else
{
    Log.Error("Data asset '{0}' does not exist in resource packages", dataAssetName);
}

Try / catch

try
{
    dataProvider.ReadData(dataAssetName);
}
catch (GameFrameworkException ex)
{
    // ex.Message contains appendErrorMessage with the underlying load failure
    Log.Error("Data load failed: {0}", ex.Message);
}

Prevention

When it happens

Trigger: A data asset load fails (ResourceComponent reports load failure) and no ReadDataFailureEventHandler is subscribed, so the callback cannot deliver the failure via event args and instead throws with the accumulated error message.

Common situations: Data asset missing from resource packs/built AssetBundles; wrong asset name passed to ReadData; resource loading infrastructure misconfigured; running in editor without the asset present.

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/594beb371365aaaa. Report an issue: GitHub.

Appendix: source

Thrown at GameFramework/Base/DataProvider/DataProvider.cs:447

            }
            finally
            {
                m_DataProviderHelper.ReleaseDataAsset(m_Owner, dataAsset);
            }
        }

        private void LoadAssetOrBinaryFailureCallback(string dataAssetName, LoadResourceStatus status, string errorMessage, object userData)
        {
            string appendErrorMessage = Utility.Text.Format("Load data failure, data asset name '{0}', status '{1}', error message '{2}'.", dataAssetName, status, errorMessage);
            if (m_ReadDataFailureEventHandler != null)
            {
                ReadDataFailureEventArgs loadDataFailureEventArgs = ReadDataFailureEventArgs.Create(dataAssetName, appendErrorMessage, userData);
                m_ReadDataFailureEventHandler(this, loadDataFailureEventArgs);
                ReferencePool.Release(loadDataFailureEventArgs);
                return;
            }

            throw new GameFrameworkException(appendErrorMessage);
        }

        private void LoadAssetUpdateCallback(string dataAssetName, float progress, object userData)
        {
            if (m_ReadDataUpdateEventHandler != null)
            {
                ReadDataUpdateEventArgs loadDataUpdateEventArgs = ReadDataUpdateEventArgs.Create(dataAssetName, progress, userData);
                m_ReadDataUpdateEventHandler(this, loadDataUpdateEventArgs);
                ReferencePool.Release(loadDataUpdateEventArgs);
            }
        }

        private void LoadAssetDependencyAssetCallback(string dataAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData)
        {
            if (m_ReadDataDependencyAssetEventHandler != null)
            {
                ReadDataDependencyAssetEventArgs loadDataDependencyAssetEventArgs = ReadDataDependencyAssetEventArgs.Create(dataAssetName, dependencyAssetName, loadedCount, totalCount, userData);
                m_ReadDataDependencyAssetEventHandler(this, loadDataDependencyAssetEventArgs);

View on GitHub (pinned to d0c010b051)