EllanJiang/GameFramework · error · GameFrameworkException

Deserialize callback is invalid.

Error message

Deserialize callback is invalid.

What it means

GameFrameworkSerializer<T> stores per-version deserialize callbacks used when reading data back from a stream. RegisterDeserializeCallback throws when the callback parameter is null, preventing a deferred NullReferenceException during Deserialize.

Solutions

  1. Pass a valid non-null DeserializeCallback delegate for the target version.
  2. Confirm the handler method still exists and its signature matches DeserializeCallback after refactors.
  3. Add a null check/log around dynamic callback resolution before registration.
  4. Ensure every version you serialize also has a matching deserialize callback registered.

Example fix

// before
serializer.RegisterDeserializeCallback(1, GetHandler()); // GetHandler() returned null
// after
var handler = GetHandler();
if (handler != null)
{
    serializer.RegisterDeserializeCallback(1, handler);
}
Defensive patterns

Strategy: validation

Validate before calling

if (callback == null) { throw new InvalidOperationException("Deserialize callback required."); }
serializer.RegisterDeserializeCallback(version, callback);

Type guard

static bool IsValidCallback(GameFrameworkSerializer<T>.DeserializeCallback cb) => cb != null;

Try / catch

try { serializer.RegisterDeserializeCallback(version, callback); } catch (GameFrameworkException) { /* log null callback registration attempt */ }

Prevention

When it happens

Trigger: Calling serializer.RegisterDeserializeCallback(version, null), typically from a typo, an unassigned delegate field, or a failed lookup that returned null.

Common situations: Registering callbacks dynamically where the reflected MethodInfo is missing, or a refactor removed the handler method while the registration call remained.

Related errors


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

Appendix: source

Thrown at GameFramework/Base/GameFrameworkSerializer.cs:87

            }

            m_SerializeCallbacks[version] = callback;
            if (version > m_LatestSerializeCallbackVersion)
            {
                m_LatestSerializeCallbackVersion = version;
            }
        }

        /// <summary>
        /// 注册反序列化回调函数。
        /// </summary>
        /// <param name="version">反序列化回调函数的版本。</param>
        /// <param name="callback">反序列化回调函数。</param>
        public void RegisterDeserializeCallback(byte version, DeserializeCallback callback)
        {
            if (callback == null)
            {
                throw new GameFrameworkException("Deserialize callback is invalid.");
            }

            m_DeserializeCallbacks[version] = callback;
        }

        /// <summary>
        /// 注册尝试从指定流获取指定键的值回调函数。
        /// </summary>
        /// <param name="version">尝试从指定流获取指定键的值回调函数的版本。</param>
        /// <param name="callback">尝试从指定流获取指定键的值回调函数。</param>
        public void RegisterTryGetValueCallback(byte version, TryGetValueCallback callback)
        {
            if (callback == null)
            {
                throw new GameFrameworkException("Try get value callback is invalid.");
            }

            m_TryGetValueCallbacks[version] = callback;

View on GitHub (pinned to d0c010b051)