egametang/ET · critical · Exception

bt handler not inherit IMActorHandler abstract class: {obj.G

Error message

bt handler not inherit IMActorHandler abstract class: {obj.GetType().FullName}

What it means

During BTDispatcher.Awake (singleton initialization at startup), every type decorated with [BTHandlerAttribute] is instantiated via Activator.CreateInstance and cast to IBTHandler. If the cast fails (the type doesn't implement IBTHandler), this exception is thrown. The message references 'IMActorHandler' but the actual required interface is IBTHandler — the message text is misleading (likely copy-pasted from actor-message handler code). This crash occurs at startup and prevents the application from starting.

Source

Thrown at Packages/cn.etetet.behaviortree/Scripts/Model/Share/BTDispatcher.cs:48

        public void Awake()
        {
            HashSet<Type> types = CodeTypes.Instance.GetTypes(typeof (BTHandlerAttribute));
            
            foreach (Type type in types)
            {
                this.Register(type);
            }
        }
        
        private void Register(Type type)
        {
            object obj = Activator.CreateInstance(type);

            IBTHandler ibtHandler = obj as IBTHandler;
            if (ibtHandler == null)
            {
                throw new Exception($"bt handler not inherit IMActorHandler abstract class: {obj.GetType().FullName}");
            }

            Type nodeType = ibtHandler.GetNodeType();
            this.btHandlers.Add(nodeType, ibtHandler);
        }
        
        
        public int Handle(BTNode node, BTEnv env)
        {
            if (node == null)
            {
                throw new Exception($"bt node is null");
            }
            if (!this.btHandlers.TryGetValue(node.GetType(), out IBTHandler ibtHandler))
            {
                throw new Exception($"not found bt handler: {node.GetType().FullName}");
            }
            int ret = ibtHandler.Handle(node, env);

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Ensure the class implements IBTHandler: add 'int Handle(BTNode node, BTEnv env)' and 'Type GetNodeType()' methods.
  2. Remove [BTHandlerAttribute] from any class that is not a behavior-tree handler.
  3. Note that the error message says 'IMActorHandler' but the interface is actually 'IBTHandler' — do not search for IMActorHandler.

Example fix

// before — has [BTHandlerAttribute] but doesn't implement IBTHandler
[BTHandler]
public class MyNodeHandler
{
    public int Handle(MyNode node, BTEnv env) { ... }
}

// after — implements IBTHandler correctly
[BTHandler]
public class MyNodeHandler: IBTHandler
{
    public int Handle(BTNode node, BTEnv env) { ... }
    public Type GetNodeType() => typeof(MyNode);
}
Defensive patterns

Strategy: type-guard

Type guard

// Type guard to verify a handler type implements IBTHandler before registration.
// (This would go in BTDispatcher.Register to prevent the crash.)

private void Register(Type type)
{
    if (!typeof(IBTHandler).IsAssignableFrom(type))
    {
        Log.Error($"Type {type.FullName} has [BTHandlerAttribute] but does not implement IBTHandler. Skipping.");
        return;
    }
    object obj = Activator.CreateInstance(type);
    IBTHandler handler = (IBTHandler)obj;
    Type nodeType = handler.GetNodeType();
    this.btHandlers.Add(nodeType, handler);
}

Prevention

When it happens

Trigger: A class is decorated with [BTHandlerAttribute] but does not implement IBTHandler (missing the int Handle(BTNode, BTEnv) and Type GetNodeType() methods). The type is in an assembly scanned by CodeTypes at startup.

Common situations: Adding a new behavior-tree node handler and forgetting to implement IBTHandler. Decorate a non-handler class (e.g., a data model) with [BTHandlerAttribute] by mistake. The IBTHandler interface was renamed but the handler class wasn't updated.

Related errors


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