{"record":{"id":"3f63939b7ee222e4","repo":"pinpoint-apm/pinpoint","slug":"parse-error-token-is-null","errorCode":null,"errorMessage":"parse error. token is null","messagePattern":"parse error\\. token is null","errorType":"validation","errorClass":"OracleConnectionStringException","httpStatus":null,"severity":"error","filePath":"agent-module/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/parser/OracleNetConnectionDescriptorTokenizer.java","lineNumber":183,"sourceCode":"        }\n        tokenPosition++;\n    }\n\n    public Token lookAheadToken() {\n        if (tokenList.size() <= tokenPosition) {\n            return null;\n        }\n        return tokenList.get(tokenPosition);\n    }\n\n    public void setPosition(int position) {\n        this.position = position;\n    }\n\n    public void checkStartToken() {\n        Token token = this.nextToken();\n        if (token == null) {\n            throw new OracleConnectionStringException(\"parse error. token is null\");\n        }\n        // We can check by == because the token object is singleton.\n        if (!(token == TOKEN_KEY_START_OBJECT)) {\n            throw new OracleConnectionStringException(\"syntax error. Expected token='(' :\" + token.getToken());\n        }\n    }\n\n    public void checkEqualToken() {\n        Token token = this.nextToken();\n        if (token == null) {\n            throw new OracleConnectionStringException(\"parse error. token is null. Expected token='='\");\n        }\n        // We can check by == because the token object is singleton.\n        if (!(token == TOKEN_EQUAL_OBJECT)) {\n            throw new OracleConnectionStringException(\"Syntax error. Expected token='=' :\" + token.getToken());\n        }\n    }\n","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/parser/OracleNetConnectionDescriptorTokenizer.java#L165-L201","documentation":"checkStartToken() consumes the first token of the descriptor and requires it to be the '(' key-start token; if nextToken() returns null (empty or exhausted input) it throws 'parse error. token is null'. The parser was handed nothing to parse after the URL prefix.","triggerScenarios":"Parsing a URL like 'jdbc:oracle:thin:@' with nothing after the '@' — the tokenizer produces no tokens and checkStartToken()'s nextToken() returns null. Also reached via parser flows that call checkStartToken on an empty remainder.","commonSituations":"Config key containing only the prefix with the descriptor in a separate/missing variable; empty environment variable substituted for the host section; trimmed URL where the descriptor got stripped.","solutions":["Provide the full descriptor after the '@', e.g. jdbc:oracle:thin:@(DESCRIPTION=...)","Check that the config/env variable holding the descriptor is non-empty and correctly wired","Fall back to the simple URL format jdbc:oracle:thin:@host:port:SID if a descriptor isn't required","Add a null/empty check on the JDBC URL in configuration loading and fail with a clear message"],"exampleFix":"// before\nString url = \"jdbc:oracle:thin:@\" + desc; // desc == \"\"\n// after\nString url = \"jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=svc)))\";","handlingStrategy":"validation","validationCode":"boolean hasDescriptorBody(String url) {\n    if (url == null) return false;\n    int at = url.indexOf('@');\n    return at != -1 && url.substring(at + 1).trim().startsWith(\"(\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    parser.parse(url);\n} catch (OracleConnectionStringException e) {\n    log.error(\"Oracle JDBC URL empty after '@': {}\", url, e);\n    throw new ConfigurationException(\"Missing descriptor after '@'\", e);\n}","preventionTips":["Check config wiring so the descriptor variable is actually populated","Reject empty or prefix-only JDBC URLs at configuration load","Fall back to jdbc:oracle:thin:@host:port:SID when no descriptor is configured"],"tags":["jdbc","oracle","empty-input","url-parsing"],"backgroundTag":"invalid-url-format","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}