EllanJiang/GameFramework · error · GameFrameworkException
Reference type is invalid.
Error message
Reference type is invalid.
What it means
ReferencePool.InternalCheckReferenceType validates a Type before a collection is created or looked up for it. If the Type itself is null, the framework cannot key any collection on it and throws 'Reference type is invalid.' This is the first of several type validation gates applied on every Acquire, Release, Add, Remove, and RemoveAll call.
Solutions
- Fix the code that produced the null Type — check Type.GetType results for null before passing them to ReferencePool.
- Use the generic APIs (Acquire<T>, Add<T>, Remove<T>) where possible so the compiler guarantees a non-null type.
- Verify the assembly containing the reference class is loaded and the type name string is fully qualified and correct.
Example fix
// before
var type = Type.GetType("Game.MyReference"); // null on typo/missing assembly
ReferencePool.Add(type, 10);
// after
var type = typeof(Game.MyReference);
ReferencePool.Add(type, 10); Defensive patterns
Strategy: validation
Validate before calling
if (type == null)
{
throw new ArgumentException("Reference type name could not be resolved.", nameof(type));
}
ReferencePool.Add(type, count); Type guard
bool IsValidPoolType(Type t) => t != null;
Try / catch
var type = Type.GetType(typeName);
if (type == null)
{
// fail fast with the bad type name before touching the pool
throw new TypeLoadException("Unknown reference type: " + typeName);
}
try { ReferencePool.Add(type, count); }
catch (GameFrameworkException ex) when (ex.Message == "Reference type is invalid.") { /* log typeName */ } Prevention
- Prefer generic APIs (Acquire<T>/Add<T>) so the type is compile-time guaranteed non-null.
- Never ignore a null result from Type.GetType — check and throw with the offending name.
- Keep fully-qualified, assembly-qualified type names in any config that drives pool warm-up.
When it happens
Trigger: Reaching InternalCheckReferenceType with a null Type — possible via non-generic overloads (e.g. Release(IReference) paths that call GetType() on a null is prevented earlier, but reflection-based or Type-passing overloads like Acquire(Type)/Add(Type,...) can pass null), usually from misconfigured reflection or a failed type lookup.
Common situations: Reflection-driven pooling where Type.GetType("Namespace.Class") returns null due to a typo or missing assembly; configuration-driven pool warm-up that stores type names and resolves them at startup; generic wrappers caching a Type that was never resolved.
Related errors
- Reference is invalid.
- Reference type is not a non-abstract class type.
- Reference type ' ' is invalid.
- ReferenceType is invalid.
- Type is invalid.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/e765309a134c67fa.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/Base/ReferencePool/ReferencePool.cs:191
/// 从引用池中移除所有的引用。
/// </summary>
/// <param name="referenceType">引用类型。</param>
public static void RemoveAll(Type referenceType)
{
InternalCheckReferenceType(referenceType);
GetReferenceCollection(referenceType).RemoveAll();
}
private static void InternalCheckReferenceType(Type referenceType)
{
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.");View on GitHub (pinned to d0c010b051)