{"record":{"id":"c60405abe85b73fd","repo":"egametang/ET","slug":"not-found-bt-handler-node-gettype-fullname","errorCode":null,"errorMessage":"not found bt handler: {node.GetType().FullName}","messagePattern":"not found bt handler: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.behaviortree/Scripts/Model/Share/BTDispatcher.cs","lineNumber":64,"sourceCode":"            if (ibtHandler == null)\n            {\n                throw new Exception($\"bt handler not inherit IMActorHandler abstract class: {obj.GetType().FullName}\");\n            }\n\n            Type nodeType = ibtHandler.GetNodeType();\n            this.btHandlers.Add(nodeType, ibtHandler);\n        }\n        \n        \n        public int Handle(BTNode node, BTEnv env)\n        {\n            if (node == null)\n            {\n                throw new Exception($\"bt node is null\");\n            }\n            if (!this.btHandlers.TryGetValue(node.GetType(), out IBTHandler ibtHandler))\n            {\n                throw new Exception($\"not found bt handler: {node.GetType().FullName}\");\n            }\n            int ret = ibtHandler.Handle(node, env);\n            \n#if UNITY_EDITOR\n            env.AddSnapshot($\"Node {node.GetType().Name} {node.Id} return {ret}\");\n#endif\n            return ret;\n        }\n    }\n}\n","sourceCodeStart":46,"sourceCodeEnd":75,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.behaviortree/Scripts/Model/Share/BTDispatcher.cs#L46-L75","documentation":"BTDispatcher.Handle looked up node.GetType() in its internal btHandlers dictionary and found no registered IBTHandler for that node type. The dictionary is populated at startup by scanning all [BTHandlerAttribute]-decorated types and keying them by the result of GetNodeType(). If no handler's GetNodeType() returns this node's type, dispatch fails.","triggerScenarios":"Dispatching a BTNode whose concrete runtime type has no corresponding handler. This happens when a new BTNode subclass is added without a matching handler, or when a handler's GetNodeType() returns a different (base) type than the node being dispatched.","commonSituations":"A new BTNode subtype was created but no [BTHandlerAttribute] handler class was written for it. A handler's GetNodeType() returns typeof(BaseNode) instead of typeof(ConcreteNode). The handler class is missing the [BTHandlerAttribute] decoration so it was never registered. The handler is in an assembly not scanned by CodeTypes.","solutions":["Create a class that implements IBTHandler, decorate it with [BTHandlerAttribute], and have its GetNodeType() return the exact BTNode subtype being dispatched.","Verify GetNodeType() returns the concrete node type (typeof(MyNode)), not a base type.","Ensure the handler class is in an assembly included in the CodeTypes scan (check assembly definitions and [CodeProcess] attributes).","Check that the handler class has [BTHandlerAttribute] — without it, BTDispatcher.Awake won't register it."],"exampleFix":"// before — MyNode has no handler, dispatch throws\nBTDispatcher.Instance.Handle(myNode, env);\n\n// after — add a handler for MyNode\n[BTHandler]\npublic class MyNodeHandler: IBTHandler\n{\n    public Type GetNodeType() => typeof(MyNode);\n    public int Handle(BTNode node, BTEnv env)\n    {\n        var myNode = (MyNode)node;\n        // ... execute node logic ...\n        return BTResult.Success;\n    }\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Guard before dispatching (requires a public method on BTDispatcher):\n// Add to BTDispatcher:\n//   public bool HasHandler(BTNode node) => btHandlers.ContainsKey(node.GetType());\n//\n// Then at the call site:\nif (!BTDispatcher.Instance.HasHandler(node))\n{\n    Log.Error($\"No BT handler registered for node type: {node.GetType().FullName}\");\n    return BTResult.Failure;\n}\nint ret = BTDispatcher.Instance.Handle(node, env);","tryCatchPattern":null,"preventionTips":["For every new BTNode subclass, create a matching [BTHandlerAttribute] handler whose GetNodeType() returns the exact subtype.","Verify GetNodeType() returns the concrete node type, not a base type.","Ensure handler classes have [BTHandlerAttribute] and are in assemblies scanned by CodeTypes.","Add a startup test that asserts every BTNode subtype used in trees has a registered handler."],"tags":["behavior-tree","handler-not-found","missing-handler","dispatch","registration"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}