egametang/ET · error · Exception
condition group error code only support leaf or not node: {n
Error message
condition group error code only support leaf or not node: {node.GetType().Name} What it means
Thrown by ApplyErrorCode when the `:errorCode` suffix is attached to a parenthesized GROUP expression whose resulting node is neither a leaf compare nor a BTNot. The framework only knows how to push an ErrorCode onto BTNumericCompare / generic BTCondition (via field reflection) / BTNot, so applying it to a compound AND/OR node (which becomes BTSequence/BTSelector) is rejected.
Source
Thrown at Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs:267
if (node is BTNumericCompare numericCompare)
{
numericCompare.ErrorCode = errorCode;
return;
}
if (node is BTCondition condition)
{
this.SetCompareField(condition, nameof(BTNumericCompare.ErrorCode), errorCode);
return;
}
if (node is BTNot not)
{
not.ErrorCode = errorCode;
return;
}
throw new Exception($"condition group error code only support leaf or not node: {node.GetType().Name}");
}
private void SetCompareField(BTCondition node, string fieldName, object value)
{
FieldInfo fieldInfo = node.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
if (fieldInfo == null)
{
throw new Exception($"condition node field not found: {node.GetType().FullName}.{fieldName}");
}
fieldInfo.SetValue(node, value);
}
private void SetOwnerKeyField(BTCondition node, string ownerKey)
{
FieldInfo fieldInfo = node.GetType().GetField(nameof(BTNumericCompare.OwnerKey), BindingFlags.Instance | BindingFlags.Public);
if (fieldInfo == null)
{View on GitHub (pinned to 5cab01f7a8)
Solutions
- Move the `:errorCode` onto each leaf compare inside the group instead of the group node, e.g. `(HP > 0:1000 && MP > 0:1000)`.
- If the whole group should share one code, wrap the group in a BTNot-free leaf or assign codes per leaf at design time.
- Document in the condition DSL that group-level error codes are unsupported except for `!leaf` (BTNot) forms.
Example fix
// before (HP > 0 && MP > 0):1000 // after (HP > 0:1000 && MP > 0:1000)
Defensive patterns
Strategy: validation
Validate before calling
// reject group-level error codes in the DSL before parsing
bool HasGroupErrorCode(string expr)
{
// a ')' immediately followed (ignoring spaces) by ':' indicates a group-level code
int close = expr.IndexOf(')');
return close >= 0 && expr.Skip(close + 1).Any(c => !char.IsWhiteSpace(c)) && expr.IndexOf(':', close) == close + 1;
} Prevention
- Document that `:code` may only attach to a leaf compare or a `!leaf` form.
- Lint condition cells: flag any `):` (paren immediately followed by colon) as unsupported.
- Train designers to put error codes on individual leaves.
When it happens
Trigger: Attaching an error code to a grouped boolean compound expression, e.g. `(HP > 0 && MP > 0):1000` (parenthesizing an AND yields a BTSequence) or `(A || B):5` (BTSelector). The colon-after-paren path at ParsePrimary line 95 calls ApplyErrorCode on that sequence/selector node.
Common situations: Designer wraps a sub-expression in parentheses to set a shared error code for the whole group, expecting the code to fan out to children; refactor that flattens a leaf into an AND without removing the `:code` suffix.
Related errors
- condition error code out of range: {token.Number}
- condition token expected: {type}, actual: {token.Text}
- condition variable not registered: {variable}
- condition variable node create error: {nodeType.FullName}
- condition variable reference invalid: {text}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/4dff3b8be9d40f31.
Report an issue: GitHub.