{"record":{"id":"69ccc3f88ecee4da","repo":"egametang/ET","slug":"condition-variable-node-must-inherit-btcondition","errorCode":null,"errorMessage":"condition variable node must inherit BTCondition: {type.FullName}","messagePattern":"condition variable node must inherit BTCondition: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionVariableRegistry.cs","lineNumber":22,"sourceCode":"namespace ET\n{\n    [CodeProcess]\n    [AllowInstance]\n    public class ConditionVariableRegistry : Singleton<ConditionVariableRegistry>, ISingletonAwake\n    {\n        private readonly Dictionary<string, Type> variableNodeTypes = new();\n        private readonly Dictionary<string, NumericType> numericTypes = new();\n\n        public void Awake()\n        {\n            this.RegisterNumericTypes();\n            \n            HashSet<Type> types = CodeTypes.Instance.GetTypes(typeof(ConditionVariableAttribute));\n            foreach (Type type in types)\n            {\n                if (!typeof(BTCondition).IsAssignableFrom(type))\n                {\n                    throw new Exception($\"condition variable node must inherit BTCondition: {type.FullName}\");\n                }\n\n                object[] attrs = type.GetCustomAttributes(typeof(ConditionVariableAttribute), false);\n                foreach (object attr in attrs)\n                {\n                    ConditionVariableAttribute conditionVariableAttribute = (ConditionVariableAttribute)attr;\n                    if (string.IsNullOrWhiteSpace(conditionVariableAttribute.Variable))\n                    {\n                        throw new Exception($\"condition variable is empty: {type.FullName}\");\n                    }\n\n                    if (!this.variableNodeTypes.TryAdd(conditionVariableAttribute.Variable, type))\n                    {\n                        throw new Exception($\"duplicate condition variable: {conditionVariableAttribute.Variable}\");\n                    }\n                }\n            }\n        }","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionVariableRegistry.cs#L4-L40","documentation":"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.","triggerScenarios":"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.","commonSituations":"A developer copies the attribute onto a helper/utility class; a node was refactored to inherit a different base and no longer satisfies BTCondition.","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."],"exampleFix":"// before\n[ConditionVariable(\"MyVar\")]\npublic class MyVarNode : BTNode { }\n// after\n[ConditionVariable(\"MyVar\")]\npublic class MyVarNode : BTCondition { }","handlingStrategy":"type-guard","validationCode":"// in a bootstrap test\nforeach (Type t in CodeTypes.Instance.GetTypes(typeof(ConditionVariableAttribute)))\n{\n    if (!typeof(BTCondition).IsAssignableFrom(t))\n        Assert.Fail($\"{t.FullName} must inherit BTCondition\");\n}","typeGuard":"static bool IsConditionNode(Type t) => typeof(BTCondition).IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["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."],"tags":["csharp","unity","conditionexpr","attribute","bootstrap","registration"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}