{"record":{"id":"c3aa646c4423cba9","repo":"JamesNK/Newtonsoft.Json","slug":"path-ended-with-open-indexer","errorCode":null,"errorMessage":"Path ended with open indexer.","messagePattern":"Path ended with open indexer\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Linq/JsonPath/JPath.cs","lineNumber":385,"sourceCode":"                    start = _currentIndex;\n                    end = null;\n                }\n                else if (!char.IsDigit(currentCharacter) && currentCharacter != '-')\n                {\n                    throw new JsonException(\"Unexpected character while parsing path indexer: \" + currentCharacter);\n                }\n                else\n                {\n                    if (end != null)\n                    {\n                        throw new JsonException(\"Unexpected character while parsing path indexer: \" + currentCharacter);\n                    }\n\n                    _currentIndex++;\n                }\n            }\n\n            throw new JsonException(\"Path ended with open indexer.\");\n        }\n\n        private void EatWhitespace()\n        {\n            while (_currentIndex < _expression.Length)\n            {\n                if (_expression[_currentIndex] != ' ')\n                {\n                    break;\n                }\n\n                _currentIndex++;\n            }\n        }\n\n        private PathFilter ParseQuery(char indexerCloseChar, bool scan)\n        {\n            _currentIndex++;","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Linq/JsonPath/JPath.cs#L367-L403","documentation":"Thrown by the JPath array-indexer parser when the expression ends while still inside an open indexer, i.e. the closing ']' was never reached. The parser loop exhausts the string at JPath.cs:384-385 and throws because the indexer is unbalanced. (The same message is also used by EnsureLength checks earlier when content runs out mid-indexer.)","triggerScenarios":"A path like token.SelectToken(\"$[1\") or \"$[\" where the opening '[' has no matching ']'. The parser enters ParseArrayIndexer and runs off the end of the string.","commonSituations":"Truncating a path string; building a path with string concatenation that omits the closing bracket; a formatting bug that drops trailing characters.","solutions":["Add the missing closing ']' to balance the indexer, e.g. $[1].","When building paths dynamically, ensure every '[' has a matching ']'.","Validate bracket balance before passing the path to SelectToken."],"exampleFix":"// before\ntoken.SelectToken(\"$.data[1\");\n\n// after\ntoken.SelectToken(\"$.data[1]\");","handlingStrategy":"validation","validationCode":"// Verify bracket balance before querying\nstatic bool BracketsBalanced(string path)\n{\n    int depth = 0;\n    foreach (char c in path)\n    {\n        if (c == '[') depth++;\n        else if (c == ']') depth--;\n        if (depth < 0) return false;\n    }\n    return depth == 0;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    token.SelectToken(path);\n}\ncatch (JsonException ex) when (ex.Message.Contains(\"Path ended with open indexer\"))\n{\n    path += \"]\"; // attempt to close the indexer\n}","preventionTips":["Ensure every '[' has a matching ']' in the path.","Use a path-builder that tracks and closes open indexers.","Validate bracket balance before calling SelectToken."],"tags":["jsonpath","parse-error","syntax"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}