{"record":{"id":"ffe279078566eaae","repo":"egametang/ET","slug":"condition-variable-node-create-error-nodetype-fu","errorCode":null,"errorMessage":"condition variable node create error: {nodeType.FullName}","messagePattern":"condition variable node create error: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs","lineNumber":130,"sourceCode":"            {\n                errorCode = this.ReadErrorCode();\n            }\n\n            ConditionVariableRegistry registry = ConditionVariableRegistry.Instance;\n            if (registry == null)\n            {\n                throw new Exception(\"condition variable registry is not initialized\");\n            }\n\n            if (!registry.TryGetNodeType(variable, out Type nodeType))\n            {\n                throw new Exception($\"condition variable not registered: {variable}\");\n            }\n\n            BTCondition node = Activator.CreateInstance(nodeType) as BTCondition;\n            if (node == null)\n            {\n                throw new Exception($\"condition variable node create error: {nodeType.FullName}\");\n            }\n\n            node.Id = this.NextNodeId();\n            if (node is BTNumericCompare numericCompare)\n            {\n                if (hasParams)\n                {\n                    this.SetParamsField(numericCompare, paramValues);\n                }\n\n                if (registry.TryGetNumericType(variable, out NumericType numericType))\n                {\n                    numericCompare.NumericType = numericType;\n                }\n\n                this.SetOwnerKeyField(numericCompare, ownerKey);\n                numericCompare.Op = op;\n                numericCompare.Value = valueToken.Number;","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs#L112-L148","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the registered BTCondition subclass has a public parameterless constructor.","Make sure the type is concrete (not abstract).","If using HybridCLR/IL2CPP, confirm the type is not stripped (add AOT/preserve hints as the harness requires).","Do not put [ConditionVariable] on abstract base classes."],"exampleFix":"// before\n[ConditionVariable(\"MyCond\")]\npublic abstract class MyCondNode : BTCondition { }  // abstract -> Activator returns null -> [57]\n\n// after\n[ConditionVariable(\"MyCond\")]\npublic class MyCondNode : BTCondition\n{\n    public MyCondNode() { }\n}","handlingStrategy":"validation","validationCode":"// At startup, verify registered node types are instantiable BTConditions:\n// foreach type in registry: require concrete, public parameterless ctor, assignable to BTCondition.","typeGuard":"static bool IsInstantiableBTCondition(Type t) =>\n    typeof(BTCondition).IsAssignableFrom(t) && !t.IsAbstract &&\n    t.GetConstructor(Type.EmptyTypes) != null;","tryCatchPattern":null,"preventionTips":["Give every [ConditionVariable] node a public parameterless constructor.","Never put [ConditionVariable] on abstract classes.","Under HybridCLR/IL2CPP, ensure types are not stripped."],"tags":["conditionexpr","parser","reflection","activation","csharp","unity"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}