{"record":{"id":"5b4e8378580d3f2e","repo":"elastic/elasticsearch","slug":"expected-text-at-but-found","errorCode":null,"errorMessage":"Expected text at {} but found {}","messagePattern":"Expected text at (.+?) but found (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/x-content/impl/src/main/java/org/elasticsearch/xcontent/provider/json/JsonXContentParser.java","lineNumber":165,"sourceCode":"    public XContentString optimizedText() throws IOException {\n        if (currentToken().isValue() == false) {\n            throwOnNoText();\n        }\n        var parser = this.parser;\n        if (parser instanceof FilteringParserDelegate delegate) {\n            parser = delegate.delegate();\n        }\n        if (parser instanceof OptimizedTextCapable optimizedTextCapableParser) {\n            var bytesRef = optimizedTextCapableParser.getValueAsText();\n            if (bytesRef != null) {\n                return bytesRef;\n            }\n        }\n        return new Text(text());\n    }\n\n    private void throwOnNoText() {\n        throw new IllegalArgumentException(\"Expected text at \" + getTokenLocation() + \" but found \" + currentToken());\n    }\n\n    @Override\n    public CharBuffer charBuffer() throws IOException {\n        try {\n            return CharBuffer.wrap(parser.getTextCharacters(), parser.getTextOffset(), parser.getTextLength());\n        } catch (IOException e) {\n            throw handleParserException(e);\n        }\n    }\n\n    @Override\n    public Object objectText() throws IOException {\n        JsonToken currentToken = parser.getCurrentToken();\n        if (currentToken == JsonToken.VALUE_STRING) {\n            return text();\n        } else if (currentToken == JsonToken.VALUE_NUMBER_INT || currentToken == JsonToken.VALUE_NUMBER_FLOAT) {\n            return parser.getNumberValue();","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/x-content/impl/src/main/java/org/elasticsearch/xcontent/provider/json/JsonXContentParser.java#L147-L183","documentation":"throwOnNoText is called when the caller asked for text (e.g. text(), optimizedText(), or charBuffer()) but the current token is not a value token that carries text - for example the parser is positioned on START_OBJECT, START_ARRAY, FIELD_NAME, or END_*. The exception names the token location and the offending currentToken().","triggerScenarios":"Calling a text-expecting method on JsonXContentParser when currentToken() is not a scalar value token (VALUE_STRING, VALUE_NUMBER, VALUE_TRUE, etc.). The optimized-text path also falls back to text() and calls throwOnNoText if the value-as-text lookup returns null.","commonSituations":"Forgetting to call nextToken() before reading text; reading text() at FIELD_NAME position expecting the field's value; consuming a token type the caller did not check; an off-by-one in a manual token loop.","solutions":["Always advance the parser to a value token (via nextToken()) before calling text()","Switch on currentToken() and only call text() for VALUE_* tokens","Use nextFieldName()/nextString() helpers that handle positioning for you"],"exampleFix":"// before\nparser.nextToken(); // lands on FIELD_NAME \"name\"\nString v = parser.text(); // throws - FIELD_NAME is not a value\n// after\nparser.nextToken(); // FIELD_NAME \"name\"\nparser.nextToken(); // VALUE_STRING\nString v = parser.text();","handlingStrategy":"type-guard","validationCode":"XContentParser.Token t = parser.currentToken();\nif (t == null || !t.isValue()) {\n    throw new IllegalStateException(\"expected value token, got \" + t);\n}\nString v = parser.text();","typeGuard":"static boolean isValueToken(XContentParser.Token t) {\n    return t != null && t.isValue();\n}","tryCatchPattern":"try { parser.text(); }\ncatch (IllegalArgumentException e) { /* advance token first */ }","preventionTips":["Always advance to a value token before text()\nSwitch on currentToken() and only read text for VALUE_*\nUse nextFieldName/nextString helpers for common patterns"],"tags":["x-content","json","parsing","input-validation"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}