{"record":{"id":"032630b8f2b6846f","repo":"JamesNK/Newtonsoft.Json","slug":"unexpected-end-while-parsing-path","errorCode":null,"errorMessage":"Unexpected end while parsing path.","messagePattern":"Unexpected end while parsing path\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Linq/JsonPath/JPath.cs","lineNumber":194,"sourceCode":"            }\n\n            bool atPathEnd = (_currentIndex == _expression.Length);\n\n            if (_currentIndex > currentPartStartIndex)\n            {\n                string? member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex).TrimEnd();\n                if (member == \"*\")\n                {\n                    member = null;\n                }\n                filters.Add(CreatePathFilter(member, scan));\n            }\n            else\n            {\n                // no field name following dot in path and at end of base path/query\n                if (followingDot && (atPathEnd || query))\n                {\n                    throw new JsonException(\"Unexpected end while parsing path.\");\n                }\n            }\n\n            return atPathEnd;\n        }\n\n        private static PathFilter CreatePathFilter(string? member, bool scan)\n        {\n            PathFilter filter = (scan) ? (PathFilter)new ScanFilter(member) : new FieldFilter(member);\n            return filter;\n        }\n\n        private PathFilter ParseIndexer(char indexerOpenChar, bool scan)\n        {\n            _currentIndex++;\n\n            char indexerCloseChar = (indexerOpenChar == '[') ? ']' : ')';\n","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Linq/JsonPath/JPath.cs#L176-L212","documentation":"Thrown by the JPath parser when the path ends (or a query boundary is reached) immediately after a dot, with no field name following it. ParsePath detects the followingDot flag combined with the end of the base path and rejects the dangling separator.","triggerScenarios":"A path like token.SelectToken(\"$.data.\") or \"$..\" where a dot is the last meaningful token. ParsePath.cs:192-194 fires because followingDot is true and atPathEnd is true with no member text.","commonSituations":"Trailing dots left by string trimming or concatenation bugs; building a path in a loop that appends '.' unconditionally; a recursive '..' with nothing after it.","solutions":["Remove the trailing dot from the path.","When building paths dynamically, append '.' only between segments, never after the last one.","Trim trailing dots from the final expression string before passing it to SelectToken."],"exampleFix":"// before\nvar path = \"$.data.\";\ntoken.SelectToken(path);\n\n// after\nvar path = \"$.data\";\ntoken.SelectToken(path);","handlingStrategy":"validation","validationCode":"// Trim trailing dots/separators before querying\npath = path.TrimEnd('.');\ntoken.SelectToken(path);","typeGuard":null,"tryCatchPattern":"try\n{\n    token.SelectToken(path);\n}\ncatch (JsonException ex) when (ex.Message.Contains(\"Unexpected end while parsing path\"))\n{\n    path = path.TrimEnd('.');\n    token.SelectToken(path);\n}","preventionTips":["Trim trailing dots from any path before passing it to SelectToken.","When appending segments in a loop, add '.' only between items.","Validate that no path segment is empty after splitting on '.'."],"tags":["jsonpath","parse-error","syntax"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}