{"record":{"id":"5a40a243b57f813e","repo":"egametang/ET","slug":"condition-variable-reference-invalid-text","errorCode":null,"errorMessage":"condition variable reference invalid: {text}","messagePattern":"condition variable reference invalid: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs","lineNumber":183,"sourceCode":"            this.SetCompareField(node, nameof(BTNumericCompare.ErrorCode), errorCode);\n            return node;\n        }\n\n        private void ReadVariable(string text, out string ownerKey, out string variable, out bool hasOwnerKey)\n        {\n            ownerKey = ConditionExprEnvKeys.Unit;\n            variable = text;\n            hasOwnerKey = false;\n\n            int dotIndex = text.IndexOf('.');\n            if (dotIndex < 0)\n            {\n                return;\n            }\n\n            if (dotIndex == 0 || dotIndex == text.Length - 1 || dotIndex != text.LastIndexOf('.'))\n            {\n                throw new Exception($\"condition variable reference invalid: {text}\");\n            }\n\n            ownerKey = text.Substring(0, dotIndex);\n            variable = text.Substring(dotIndex + 1);\n            hasOwnerKey = true;\n        }\n\n        private string[] ReadParams(out bool hasParams)\n        {\n            hasParams = false;\n            if (!this.Match(ConditionTokenType.LeftParen))\n            {\n                return Array.Empty<string>();\n            }\n\n            hasParams = true;\n            List<string> paramValues = new();\n            if (this.Match(ConditionTokenType.RightParen))","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs#L165-L201","documentation":"Thrown by ConditionExprParser.ReadVariable when an OwnerKey.Variable reference is malformed. The grammar allows exactly one dot separating a registered owner key from a variable (e.g. Unit1.HP). The reference is invalid if the dot is at the start ('.HP'), at the end ('Unit.'), or if there is more than one dot ('A.B.C').","triggerScenarios":"An expression like '.HP > 0' (leading dot), 'Unit. > 0' (trailing dot), or 'Unit.Sub.HP > 0' (two dots). Only a single-level 'OwnerKey.Variable' is permitted.","commonSituations":"Author attempting nested member access that the grammar does not support; a stray dot typed at the start/end of the variable; copy-paste introducing an extra dot.","solutions":["Use exactly one dot in the form 'OwnerKey.Variable'.","Remove leading/trailing dots from the variable token.","Do not attempt multi-level dotted paths; flatten to a single registered variable name.","Confirm OwnerKey is a key previously passed to BTEnv.AddEntity."],"exampleFix":"// before (expression cell)\n//   Unit.Sub.HP > 0\n// after\n//   Unit.HP > 0","handlingStrategy":"validation","validationCode":"// Validate variable token shape before parse: a dotted ref must have exactly one dot,\n// not at start or end:\nint dots = text.Count(c => c == '.');\nbool ok = dots == 0 || (dots == 1 && text[0] != '.' && text[^1] != '.');","typeGuard":"static bool IsValidVariableRef(string text)\n{\n    int i = text.IndexOf('.');\n    return i < 0 || (i > 0 && i < text.Length - 1 && i == text.LastIndexOf('.'));\n}","tryCatchPattern":null,"preventionTips":["Use only single-level 'OwnerKey.Variable' references.","Avoid leading/trailing dots and nested paths.","Lint dotted references during config import."],"tags":["conditionexpr","parser","variable","syntax","config","csharp","unity"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}