egametang/ET · critical · Exception

duplicate condition variable: {conditionVariableAttribute.Va

Error message

duplicate condition variable: {conditionVariableAttribute.Variable}

What it means

Thrown during ConditionVariableRegistry.Awake() when TryAdd fails, meaning two [ConditionVariable] registrations (or a registration colliding with a built-in NumericType name) claimed the same variable string. The registry is a single Dictionary keyed by variable name, so duplicates are rejected to keep parser lookup unambiguous.

Source

Thrown at Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionVariableRegistry.cs:36

            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}");
                    }
                }
            }
        }

        private void RegisterNumericTypes()
        {
            foreach (NumericType numericType in Enum.GetValues(typeof(NumericType)))
            {
                string variable = numericType.ToString();
                this.numericTypes.Add(variable, numericType);
                this.variableNodeTypes.Add(variable, typeof(BTNumericCompare));
            }
        }

        public bool TryGetNodeType(string variable, out Type nodeType)
        {
            return this.variableNodeTypes.TryGetValue(variable, out nodeType);

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Rename one of the conflicting variables so each name maps to exactly one node type.
  2. If colliding with a NumericType name, pick a different custom variable name or remove the redundant custom node.
  3. Search the codebase for `[ConditionVariable("<name>")]` and the NumericType enum to find both sources.

Example fix

// before
[ConditionVariable("HP")]
public class CustomHpNode : BTCondition { }
// (HP already a NumericType)
// after
[ConditionVariable("CustomHp")]
public class CustomHpNode : BTCondition { }
Defensive patterns

Strategy: validation

Validate before calling

// detect duplicate variable names at startup before the registry throws
var seen = new HashSet<string>();
foreach (Type t in CodeTypes.Instance.GetTypes(typeof(ConditionVariableAttribute)))
    foreach (ConditionVariableAttribute a in t.GetCustomAttributes(typeof(ConditionVariableAttribute), false))
        if (!seen.Add(a.Variable))
            Console.Error.WriteLine($"duplicate condition variable: {a.Variable} on {t.FullName}");

Prevention

When it happens

Trigger: Two node classes both declare `[ConditionVariable("HP")]`; a custom variable name collides with a registered NumericType enum name (RegisterNumericTypes pre-registers each NumericType name pointing at BTNumericCompare).

Common situations: Renaming a node and forgetting the old one still carries the same attribute; introducing a new NumericType enum member whose name clashes with an existing custom variable.

Related errors


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