{"record":{"id":"3f75951be68fa399","repo":"jhy/jsoup","slug":"could-not-parse-nth-index-s-unexpected-format","errorCode":null,"errorMessage":"Could not parse nth-index '%s': unexpected format","messagePattern":"Could not parse nth-index '(.+?)': unexpected format","errorType":"exception","errorClass":"Selector.SelectorParseException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/jsoup/select/QueryParser.java","lineNumber":409,"sourceCode":"            step = 2;\n            offset = 1;\n        } else if (\"even\".equals(arg)) {\n            step = 2;\n            offset = 0;\n        } else {\n            Matcher stepOffsetM, stepM;\n            if ((stepOffsetM = NthStepOffset.matcher(arg)).matches()) {\n                if (stepOffsetM.group(3) != null) // has digits, like 3n+2 or -3n+2\n                    step = Integer.parseInt(stepOffsetM.group(1).replaceFirst(\"^\\\\+\", \"\"));\n                else // no digits, might be like n+2, or -n+2. if group(2) == \"-\", it’s -1;\n                    step = \"-\".equals(stepOffsetM.group(2)) ? -1 : 1;\n                offset =\n                    stepOffsetM.group(4) != null ? Integer.parseInt(stepOffsetM.group(4).replaceFirst(\"^\\\\+\", \"\")) : 0;\n            } else if ((stepM = NthOffset.matcher(arg)).matches()) {\n                step = 0;\n                offset = Integer.parseInt(stepM.group().replaceFirst(\"^\\\\+\", \"\"));\n            } else {\n                throw new Selector.SelectorParseException(\"Could not parse nth-index '%s': unexpected format\", arg);\n            }\n        }\n\n        return ofType\n            ? (last ? new Evaluator.IsNthLastOfType(step, offset) : new Evaluator.IsNthOfType(step, offset))\n            : (last ? new Evaluator.IsNthLastChild(step, offset) : new Evaluator.IsNthChild(step, offset));\n    }\n\n    private String consumeParens() {\n        return tq.chompBalanced('(', ')');\n    }\n\n    private int consumeIndex() {\n        String index = consumeParens().trim();\n        Validate.isTrue(StringUtil.isNumeric(index), \"Index must be numeric\");\n        return Integer.parseInt(index);\n    }\n","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/jhy/jsoup/blob/9851ac5d9c576c6888910b5a51a2362bbc978959/src/main/java/org/jsoup/select/QueryParser.java#L391-L427","documentation":"The argument to :nth-child(), :nth-last-child(), :nth-of-type() or :nth-last-of-type() did not match any of jsoup's accepted forms (odd/even/an+b, plain integers, or +n offsets), so cssNthChild threw Selector.SelectorParseException. The nth expression grammar is strict: whitespace-free an+b patterns or simple integers.","triggerScenarios":"doc.select(\"td:nth-child(2n+1 \") with stray spaces/characters, doc.select(\"li:nth-child(one)\"), doc.select(\"div:nth-child(2 n + 1)\") or any non-numeric, non-odd/even expression. Parsed in QueryParser.cssNthChild.","commonSituations":"Typos or extra whitespace inside nth parentheses; selectors generated by template code interpolating bad values; copying nth expressions from browsers that tolerate formats jsoup's regex does not.","solutions":["Rewrite the nth expression in canonical form: odd, even, an integer, or 'an+b' like 2n+1 (no spaces)","Verify the interpolated variable actually contains a valid nth expression before building the selector","Catch Selector.SelectorParseException around select() to surface the bad argument to users","Compute the element by index in Java (children().get(i)) if the pattern is too complex"],"exampleFix":"// before\nElements els = doc.select(\"li:nth-child(2 n + 1)\");\n// after\nElements els = doc.select(\"li:nth-child(2n+1)\");","handlingStrategy":"validation","validationCode":"if (!arg.matches(\"(odd|even|\\\\d+|[+-]?\\\\d*n([+-]\\\\d+)?|\\\\d+n)\")) {\n    throw new IllegalArgumentException(\"Invalid nth expression: \" + arg);\n}","typeGuard":"boolean isValidNthArg(String arg) {\n    return arg != null && arg.trim().matches(\"(odd|even|[+-]?\\\\d*n([+-]\\\\d+)?|\\\\d+)\");\n}","tryCatchPattern":"try {\n    Elements els = doc.select(\"li:nth-child(\" + arg + \")\");\n} catch (Selector.SelectorParseException e) {\n    if (e.getMessage().contains(\"nth-index\")) {\n        throw new IllegalArgumentException(\"nth expression must be odd/even/an+b: \" + arg, e);\n    }\n    throw e;\n}","preventionTips":["Keep nth expressions in canonical an+b form with no spaces","Sanitize interpolated values before building selectors","Prefer odd/even/integer forms where possible"],"tags":["jsoup","css-selector","nth-child","parse-error"],"backgroundTag":"invalid-argument-format","analyzedSha":"9851ac5d9c576c6888910b5a51a2362bbc978959","analyzedAt":"2026-09-08T15:22:04.931Z","contentChangedAt":"2026-09-08T15:22:04.931Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}