{"record":{"id":"6868f9cd63baa6a1","repo":"Unity-Technologies/UnityCsReference","slug":"invalid-character-leftsymbol-in-expression","errorCode":null,"errorMessage":"Invalid character '{leftSymbol}' in expression","messagePattern":"Invalid character '(.+?)' in expression","errorType":"exception","errorClass":"ExpressionNotValidException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Scripting/ScriptCompilation/VersionRanges.cs","lineNumber":106,"sourceCode":"            {\n                return expressionParsedData;\n            }\n\n            IVersionTypeTraits versionTypeTraits = m_versionTypeStaticFunctionalityProxy.GetVersionTypeTraits();\n\n            bool hasSeperator = Contains(expression, ',');\n            char leftSymbol = default(char);\n            char rightSymbol = default(char);\n\n            int begin = 0;\n            int end = expression.Length - 1;\n\n            if (!versionTypeTraits.IsAllowedFirstCharacter(expression[0]))\n            {\n                leftSymbol = expression[0];\n                if (!Contains(k_LeftValidSymbols, leftSymbol))\n                {\n                    throw new ExpressionNotValidException($\"Invalid character '{leftSymbol}' in expression\", expression);\n                }\n\n                begin++;\n            }\n\n            var lastChar = expression[end];\n            if (!versionTypeTraits.IsAllowedLastCharacter(lastChar))\n            {\n                rightSymbol = lastChar;\n\n                if (!Contains(k_RightValidSymbols, rightSymbol))\n                {\n                    throw new ExpressionNotValidException($\"Invalid character '{rightSymbol}' in expression\", expression);\n                }\n\n                end--;\n            }\n","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Scripting/ScriptCompilation/VersionRanges.cs#L88-L124","documentation":"Thrown by ParseExpression (VersionRanges.cs:106) when the FIRST character of the expression is neither an allowed version first-character (a digit, per both UnityVersionTypeTraits and SemVersionTypeTraits) nor one of the legal left delimiters '[' or '('. It is a lexical rejection of an unsupported opening token, raised before any structural analysis.","triggerScenarios":"Expressions whose first character is ']', ')', '<', '>', '=', whitespace, any letter (a-z), ',', '*', '+', '~', '^', etc. Concrete inputs: '>=1.0', '>1.0', '<2.0', '<=2.0', ']1.0]', ' 1.0' (leading space), 'v1.0', 'x1.0', '*1.0', '~1.0', '^1.0' (npm-style).","commonSituations":"Porting npm ('^1.0', '~1.0'), Maven, or comparison-operator ('>=1.0', '>1.0') range syntax into a Unity Version Define; pasting an expression with a leading space that the Define-Constraints trimmer does not strip (DefineConstraintsHelper trims '||'-split define tokens, not interior/leading chars of a version-range expression); using a version prefix like 'v'.","solutions":["Replace operator prefixes with the delimiter grammar: '>=1.0' -> '1.0'; '>1.0' -> '(1.0,)'; '<=2.0' -> '(,2.0]'; '<2.0' -> '(,2.0)'.","Remove any leading whitespace or version prefix: 'v1.0' -> '1.0', ' 1.0' -> '1.0'.","Replace npm caret/tilde: '^1.0' or '~1.0' -> '1.0' (or '[1.0,2.0)' if you want the caret upper bound).","Ensure the expression opens with a digit or with '[' / '('; no other opener is legal."],"exampleFix":"// before\n\">=1.0\"   // or \"^1.0.0\"  or \" 1.0\"\n// after\n\"1.0\"     // means x >= 1.0","handlingStrategy":"validation","validationCode":"// First char must be a digit, '[', or '('.\nstatic bool HasValidOpening(string e) =>\n    !string.IsNullOrEmpty(e) &&\n    (char.IsDigit(e[0]) || e[0] == '[' || e[0] == '(');\n\n// Full-shape guard also rejects bad openers:\nstatic bool IsValidVersionRangeExpression(string e) =>\n    !string.IsNullOrEmpty(e) && k_ValidRange.IsMatch(e);","typeGuard":"static bool OpensWithLegalToken(string e) =>\n    !string.IsNullOrEmpty(e) &&\n    (char.IsDigit(e[0]) || e[0] == '[' || e[0] == '(');","tryCatchPattern":"try { var def = ranges.GetExpression(expr); }\ncatch (ExpressionNotValidException ex) when (ex.Message.Contains(\"Invalid character\")) {\n    ReportToUser($\"{expr}: bad opening character. Use a digit or '[' / '('.\");\n}","preventionTips":["Do not use npm (^, ~) or comparison-operator (>=, >, <, <=) syntax; map to V / (V,) / (,V] / (,V).","Strip leading whitespace before submitting — the range trimmer does not do it for you.","Never prefix versions with 'v' or 'x'."],"tags":["unity","asmdef","version-range","script-compilation","parsing"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}