egametang/ET · error · Exception

condition variable node create error: {nodeType.FullName}

Error message

condition variable node create error: {nodeType.FullName}

What it means

Thrown by ConditionExprParser.ParseCompare when Activator.CreateInstance(nodeType) returns an object that cannot be cast to BTCondition (the 'as BTCondition' yields null). The registry Awake already enforces that registered types inherit BTCondition, so reaching here implies the type lacks a public parameterless constructor, is abstract, or was replaced after registration.

Source

Thrown at Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs:130

            {
                errorCode = this.ReadErrorCode();
            }

            ConditionVariableRegistry registry = ConditionVariableRegistry.Instance;
            if (registry == null)
            {
                throw new Exception("condition variable registry is not initialized");
            }

            if (!registry.TryGetNodeType(variable, out Type nodeType))
            {
                throw new Exception($"condition variable not registered: {variable}");
            }

            BTCondition node = Activator.CreateInstance(nodeType) as BTCondition;
            if (node == null)
            {
                throw new Exception($"condition variable node create error: {nodeType.FullName}");
            }

            node.Id = this.NextNodeId();
            if (node is BTNumericCompare numericCompare)
            {
                if (hasParams)
                {
                    this.SetParamsField(numericCompare, paramValues);
                }

                if (registry.TryGetNumericType(variable, out NumericType numericType))
                {
                    numericCompare.NumericType = numericType;
                }

                this.SetOwnerKeyField(numericCompare, ownerKey);
                numericCompare.Op = op;
                numericCompare.Value = valueToken.Number;

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Ensure the registered BTCondition subclass has a public parameterless constructor.
  2. Make sure the type is concrete (not abstract).
  3. If using HybridCLR/IL2CPP, confirm the type is not stripped (add AOT/preserve hints as the harness requires).
  4. Do not put [ConditionVariable] on abstract base classes.

Example fix

// before
[ConditionVariable("MyCond")]
public abstract class MyCondNode : BTCondition { }  // abstract -> Activator returns null -> [57]

// after
[ConditionVariable("MyCond")]
public class MyCondNode : BTCondition
{
    public MyCondNode() { }
}
Defensive patterns

Strategy: validation

Validate before calling

// At startup, verify registered node types are instantiable BTConditions:
// foreach type in registry: require concrete, public parameterless ctor, assignable to BTCondition.

Type guard

static bool IsInstantiableBTCondition(Type t) =>
    typeof(BTCondition).IsAssignableFrom(t) && !t.IsAbstract &&
    t.GetConstructor(Type.EmptyTypes) != null;

Prevention

When it happens

Trigger: A [ConditionVariable]-attributed type that has no public parameterless constructor (e.g. only a ctor with parameters), an abstract BTCondition subclass that got registered, or reflection/Activator restrictions in a trimmed/AOT environment.

Common situations: A custom condition node class with a non-default constructor; an abstract base class accidentally given [ConditionVariable]; IL2CPP/HybridCLR stripping or AOT limitations preventing Activator.CreateInstance.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/ffe279078566eaae. Report an issue: GitHub.