{"record":{"id":"b4a5406356ebd376","repo":"json-path/JsonPath","slug":"expected-s-but-found-s","errorCode":null,"errorMessage":"Expected %s but found %s","messagePattern":"Expected (.+?) but found (.+?)","errorType":"validation","errorClass":"InvalidPathException","httpStatus":null,"severity":"error","filePath":"json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java","lineNumber":92,"sourceCode":"\n    public int position(){\n        return position;\n    }\n\n    public int indexOfClosingSquareBracket(int startPosition) {\n        int readPosition = startPosition;\n        while (inBounds(readPosition)) {\n            if(charAt(readPosition) == CLOSE_SQUARE_BRACKET){\n                return readPosition;\n            }\n            readPosition++;\n        }\n        return -1;\n    }\n\n    public int indexOfMatchingCloseChar(int startPosition, char openChar, char closeChar, boolean skipStrings, boolean skipRegex) {\n        if(charAt(startPosition) != openChar){\n            throw new InvalidPathException(\"Expected \" + openChar + \" but found \" + charAt(startPosition));\n        }\n\n        int opened = 1;\n        int readPosition = startPosition + 1;\n        while (inBounds(readPosition)) {\n            if (skipStrings) {\n                char quoteChar = charAt(readPosition);\n                if (quoteChar == SINGLE_QUOTE || quoteChar == DOUBLE_QUOTE){\n                    readPosition = nextIndexOfUnescaped(readPosition, quoteChar);\n                    if(readPosition == -1){\n                        throw new InvalidPathException(\"Could not find matching close quote for \" + quoteChar + \" when parsing : \" + charSequence);\n                    }\n                    readPosition++;\n                }\n            }\n            if (skipRegex) {\n                if (charAt(readPosition) == REGEX) {\n                    readPosition = nextIndexOfUnescaped(readPosition, REGEX);","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/json-path/JsonPath/blob/62a4c9f0f65ba3f625aa0867d64c528ba72d09ec/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java#L74-L110","documentation":"CharacterIndex.indexOfMatchingCloseChar locates the closing bracket matching an opening one during path parsing. If the character at startPosition is not the expected opening char (openChar), the path text is malformed and InvalidPathException 'Expected X but found Y' is thrown, naming both characters.","triggerScenarios":"Calling indexOfClosingBracket/indexOfMatchingCloseChar against a path string where the bracket/brace/paren position does not actually hold the expected opening char — e.g. an unclosed or mismatched filter like '$[?(@.a == 1' or '$.store.book[0' during JsonPath.compile/parse.","commonSituations":"Hand-written JSON path strings with mismatched or missing brackets, braces in filter expressions [?(...)], or programmatically assembled paths where an index segment got dropped.","solutions":["Print the full path string and visually verify every [ has a matching ].","Count brackets/braces in the path before compiling (a simple balance check catches this).","Fix the malformed segment (add the missing ']' or remove the stray char).","Escape or quote literal brackets inside filter expressions correctly."],"exampleFix":"// before\nString path = \"$.store.book[?(@.price < 10\";\nPath p = JsonPath.compile(path);\n// after\nString path = \"$.store.book[?(@.price < 10)]\";\nPath p = JsonPath.compile(path);","handlingStrategy":"validation","validationCode":"long opens = path.chars().filter(c -> c == '[').count();\nlong closes = path.chars().filter(c -> c == ']').count();\nif (opens != closes) throw new IllegalArgumentException(\"Unbalanced brackets in path: \" + path);","typeGuard":null,"tryCatchPattern":"try {\n    Path p = JsonPath.compile(path);\n} catch (InvalidPathException e) {\n    throw new IllegalArgumentException(\"Malformed JSON path '\" + path + \"': \" + e.getMessage(), e);\n}","preventionTips":["Validate path bracket balance before compiling user-supplied paths.","Store paths as constants rather than concatenating strings.","Unit-test every dynamic path template with its substitutions."],"tags":["jsonpath","parsing","invalid-path","syntax"],"backgroundTag":"invalid-argument-format","analyzedSha":"62a4c9f0f65ba3f625aa0867d64c528ba72d09ec","analyzedAt":"2026-09-11T11:36:00.448Z","contentChangedAt":"2026-09-11T11:36:00.448Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}