EllanJiang/GameFramework · error · GameFrameworkException

Reference type ' ' is invalid.

Error message

Reference type '{0}' is invalid.

What it means

After confirming the type is a non-abstract class, InternalCheckReferenceType verifies the type actually implements IReference. A type that is a valid class but does not implement the pooling interface cannot be tracked or cleared by the pool, so it is rejected with a message naming the offending type's full name.

Solutions

  1. Make the pooled class implement the framework's IReference interface (implementing Clear() as required).
  2. Confirm there is only one IReference type in scope — remove stale/duplicate interface definitions from other framework copies.
  3. If the class cannot implement IReference, use a different pooling mechanism instead of ReferencePool.

Example fix

// before
public class DamageInfo { public int Amount; } // no IReference

// after
public class DamageInfo : IReference
{
    public int Amount;
    public void Clear() { Amount = 0; }
}
Defensive patterns

Strategy: type-guard

Validate before calling

System.Diagnostics.Debug.Assert(
    typeof(IReference).IsAssignableFrom(typeof(T)),
    typeof(T).FullName + " must implement IReference before pooling.");

Type guard

static bool ImplementsIReference(Type t) => typeof(IReference).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract;

Try / catch

try { ReferencePool.Acquire<T>(); }
catch (GameFrameworkException ex) when (ex.Message.Contains("is invalid") && ex.Message.Contains(typeof(T).Name))
{
    // T does not implement IReference — add the interface or use another pool
}

Prevention

When it happens

Trigger: Calling ReferencePool.Acquire<T>/Add<T>/Release/Remove with a plain class (one that implements neither IReference nor a derived interface) — often a POCO, a struct-wrapped class, or a class implementing a similarly named custom interface.

Common situations: Refactoring that moved IReference to a different namespace and left the class implementing an old/shim interface; pooling a third-party or data class that was never meant for ReferencePool; using two different IReference interfaces from different framework versions in the same project.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at GameFramework/Base/ReferencePool/ReferencePool.cs:201

        {
            if (!m_EnableStrictCheck)
            {
                return;
            }

            if (referenceType == null)
            {
                throw new GameFrameworkException("Reference type is invalid.");
            }

            if (!referenceType.IsClass || referenceType.IsAbstract)
            {
                throw new GameFrameworkException("Reference type is not a non-abstract class type.");
            }

            if (!typeof(IReference).IsAssignableFrom(referenceType))
            {
                throw new GameFrameworkException(Utility.Text.Format("Reference type '{0}' is invalid.", referenceType.FullName));
            }
        }

        private static ReferenceCollection GetReferenceCollection(Type referenceType)
        {
            if (referenceType == null)
            {
                throw new GameFrameworkException("ReferenceType is invalid.");
            }

            ReferenceCollection referenceCollection = null;
            lock (s_ReferenceCollections)
            {
                if (!s_ReferenceCollections.TryGetValue(referenceType, out referenceCollection))
                {
                    referenceCollection = new ReferenceCollection(referenceType);
                    s_ReferenceCollections.Add(referenceType, referenceCollection);
                }

View on GitHub (pinned to d0c010b051)