egametang/ET · critical · Exception
condition variable node must inherit BTCondition: {type.Full
Error message
condition variable node must inherit BTCondition: {type.FullName} What it means
Thrown during ConditionVariableRegistry.Awake() while scanning every type decorated with [ConditionVariable]. Every such type must be assignable to BTCondition because the parser later instantiates it as `Activator.CreateInstance(nodeType) as BTCondition`. A type that is not a BTCondition cannot be cast and would fail later, so registration aborts early.
Source
Thrown at Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionVariableRegistry.cs:22
namespace ET
{
[CodeProcess]
[AllowInstance]
public class ConditionVariableRegistry : Singleton<ConditionVariableRegistry>, ISingletonAwake
{
private readonly Dictionary<string, Type> variableNodeTypes = new();
private readonly Dictionary<string, NumericType> numericTypes = new();
public void Awake()
{
this.RegisterNumericTypes();
HashSet<Type> types = CodeTypes.Instance.GetTypes(typeof(ConditionVariableAttribute));
foreach (Type type in types)
{
if (!typeof(BTCondition).IsAssignableFrom(type))
{
throw new Exception($"condition variable node must inherit BTCondition: {type.FullName}");
}
object[] attrs = type.GetCustomAttributes(typeof(ConditionVariableAttribute), false);
foreach (object attr in attrs)
{
ConditionVariableAttribute conditionVariableAttribute = (ConditionVariableAttribute)attr;
if (string.IsNullOrWhiteSpace(conditionVariableAttribute.Variable))
{
throw new Exception($"condition variable is empty: {type.FullName}");
}
if (!this.variableNodeTypes.TryAdd(conditionVariableAttribute.Variable, type))
{
throw new Exception($"duplicate condition variable: {conditionVariableAttribute.Variable}");
}
}
}
}View on GitHub (pinned to 5cab01f7a8)
Solutions
- Make the attributed class derive from BTCondition (directly or transitively).
- Remove [ConditionVariable] from the offending type if it is not actually a condition node.
- Rebuild/re-scan so CodeTypes.Instance picks up the corrected inheritance.
Example fix
// before
[ConditionVariable("MyVar")]
public class MyVarNode : BTNode { }
// after
[ConditionVariable("MyVar")]
public class MyVarNode : BTCondition { } Defensive patterns
Strategy: type-guard
Validate before calling
// in a bootstrap test
foreach (Type t in CodeTypes.Instance.GetTypes(typeof(ConditionVariableAttribute)))
{
if (!typeof(BTCondition).IsAssignableFrom(t))
Assert.Fail($"{t.FullName} must inherit BTCondition");
} Type guard
static bool IsConditionNode(Type t) => typeof(BTCondition).IsAssignableFrom(t);
Prevention
- Run an assembly-scan test asserting every [ConditionVariable] type derives from BTCondition.
- Code-review the attribute usage; it is only for condition node types.
- Re-scan after inheritance refactors.
When it happens
Trigger: Applying [ConditionVariable("X")] to a plain class, struct, or a BehaviorTree node that derives from BTNode but not BTCondition; adding the attribute to a data/DTO class by mistake.
Common situations: A developer copies the attribute onto a helper/utility class; a node was refactored to inherit a different base and no longer satisfies BTCondition.
Related errors
- condition variable is empty: {type.FullName}
- duplicate condition variable: {conditionVariableAttribute.Va
- ConsoleHandler handler not inherit IConsoleHandler class: {o
- condition node field not found: {node.GetType().FullName}.{f
- condition node owner key field not found: {node.GetType().Fu
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/69ccc3f88ecee4da.
Report an issue: GitHub.