json-path/JsonPath · error · InvalidPathException

Could not find matching close quote for %s when parsing : %s

Error message

Could not find matching close quote for %s when parsing : %s

What it means

CharacterIndex.indexOfMatchingCloseChar scans a JSON path string for the bracket/paren matching an opening delimiter, optionally skipping over quoted string literals. While skipping strings it calls nextIndexOfUnescaped to find the closing unescaped quote; if none exists before the end of input, it cannot continue parsing and throws InvalidPathException. This means the path has an opening quote without a matching closing quote.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java:103

            readPosition++;
        }
        return -1;
    }

    public int indexOfMatchingCloseChar(int startPosition, char openChar, char closeChar, boolean skipStrings, boolean skipRegex) {
        if(charAt(startPosition) != openChar){
            throw new InvalidPathException("Expected " + openChar + " but found " + charAt(startPosition));
        }

        int opened = 1;
        int readPosition = startPosition + 1;
        while (inBounds(readPosition)) {
            if (skipStrings) {
                char quoteChar = charAt(readPosition);
                if (quoteChar == SINGLE_QUOTE || quoteChar == DOUBLE_QUOTE){
                    readPosition = nextIndexOfUnescaped(readPosition, quoteChar);
                    if(readPosition == -1){
                        throw new InvalidPathException("Could not find matching close quote for " + quoteChar + " when parsing : " + charSequence);
                    }
                    readPosition++;
                }
            }
            if (skipRegex) {
                if (charAt(readPosition) == REGEX) {
                    readPosition = nextIndexOfUnescaped(readPosition, REGEX);
                    if(readPosition == -1){
                        throw new InvalidPathException("Could not find matching close for " + REGEX + " when parsing regex in : " + charSequence);
                    }
                    readPosition++;
                }
            }
            if (charAt(readPosition) == openChar) {
                opened++;
            }
            if (charAt(readPosition) == closeChar) {
                opened--;

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Inspect the path string and add the missing closing quote (match single with single, double with double).
  2. Escape embedded quotes inside the literal using a backslash (\' or \") or switch the outer quote style so inner quotes need no escape.
  3. If the path is dynamically built, escape or sanitize interpolated values before embedding them in the path expression.
  4. Validate the path with JsonPath.compile() in a try/catch during input validation rather than deep inside application logic.

Example fix

// before
String path = "$[?(@.name == '" + name + ")]"; // name = O'Brien -> unterminated quote
// after
String path = "$[?(@.name == '" + name.replace("'", "\\'") + ")]";
Defensive patterns

Strategy: validation

Validate before calling

long singles = path.chars().filter(c -> c == '\'').count();
long doubles = path.chars().filter(c -> c == '"').count();
if (singles % 2 != 0 || doubles % 2 != 0) throw new IllegalArgumentException("Unbalanced quotes in path: " + path);
JsonPath.compile(path); // full syntax check before use

Try / catch

try {
    return JsonPath.read(document, path);
} catch (InvalidPathException e) {
    log.error("Malformed path (unclosed quote?): {}", path, e);
    throw new IllegalArgumentException("Invalid JSON path", e);
}

Prevention

When it happens

Trigger: Calling JsonPath.parse/JsonPath.compile/read with a path whose filter or bracket segment contains an opening single or double quote that is never closed with an unescaped matching quote, e.g. "$[?(@.name == 'foo)]" or "$['key".

Common situations: Paths built by string concatenation where interpolated values contain quotes; forgetting to escape a quote inside a filter expression; copy-pasting JSON path examples where a quote was dropped; generating paths dynamically in scripts whose values contain apostrophes (O'Brien) inside single-quoted literals.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11). Data as JSON: /api/errors/b5364beae321c979. Report an issue: GitHub.