{"record":{"id":"4dff3b8be9d40f31","repo":"egametang/ET","slug":"condition-group-error-code-only-support-leaf-or-no","errorCode":null,"errorMessage":"condition group error code only support leaf or not node: {node.GetType().Name}","messagePattern":"condition group error code only support leaf or not node: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs","lineNumber":267,"sourceCode":"            if (node is BTNumericCompare numericCompare)\n            {\n                numericCompare.ErrorCode = errorCode;\n                return;\n            }\n\n            if (node is BTCondition condition)\n            {\n                this.SetCompareField(condition, nameof(BTNumericCompare.ErrorCode), errorCode);\n                return;\n            }\n\n            if (node is BTNot not)\n            {\n                not.ErrorCode = errorCode;\n                return;\n            }\n\n            throw new Exception($\"condition group error code only support leaf or not node: {node.GetType().Name}\");\n        }\n\n        private void SetCompareField(BTCondition node, string fieldName, object value)\n        {\n            FieldInfo fieldInfo = node.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);\n            if (fieldInfo == null)\n            {\n                throw new Exception($\"condition node field not found: {node.GetType().FullName}.{fieldName}\");\n            }\n\n            fieldInfo.SetValue(node, value);\n        }\n\n        private void SetOwnerKeyField(BTCondition node, string ownerKey)\n        {\n            FieldInfo fieldInfo = node.GetType().GetField(nameof(BTNumericCompare.OwnerKey), BindingFlags.Instance | BindingFlags.Public);\n            if (fieldInfo == null)\n            {","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs#L249-L285","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n(HP > 0 && MP > 0):1000\n// after\n(HP > 0:1000 && MP > 0:1000)","handlingStrategy":"validation","validationCode":"// reject group-level error codes in the DSL before parsing\nbool HasGroupErrorCode(string expr)\n{\n    // a ')' immediately followed (ignoring spaces) by ':' indicates a group-level code\n    int close = expr.IndexOf(')');\n    return close >= 0 && expr.Skip(close + 1).Any(c => !char.IsWhiteSpace(c)) && expr.IndexOf(':', close) == close + 1;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["csharp","unity","conditionexpr","parser","config-data"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}