{"record":{"id":"0f1eb7f536f65a71","repo":"apache/beam","slug":"jdbc-url-cannot-be-null-or-empty","errorCode":null,"errorMessage":"JDBC URL cannot be null or empty","messagePattern":"JDBC URL cannot be null or empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/clickhouse/src/main/java/org/apache/beam/sdk/io/clickhouse/ClickHouseJdbcUrlParser.java","lineNumber":92,"sourceCode":"  /**\n   * Parses a ClickHouse JDBC URL into its components.\n   *\n   * <p>Supported formats:\n   *\n   * <ul>\n   *   <li>jdbc:clickhouse://host:port/database?param=value\n   *   <li>jdbc:clickhouse:http://host:port/database?param=value\n   *   <li>jdbc:clickhouse:https://host:port/database?param=value\n   *   <li>jdbc:ch://host:port/database?param=value (ClickHouse JDBC driver shorthand)\n   * </ul>\n   *\n   * @param jdbcUrl the JDBC URL to parse\n   * @return ParsedJdbcUrl containing the HTTP/HTTPS URL, database, and properties\n   * @throws IllegalArgumentException if the URL format is invalid\n   */\n  static ParsedJdbcUrl parse(String jdbcUrl) {\n    if (Strings.isNullOrEmpty(jdbcUrl)) {\n      throw new IllegalArgumentException(\"JDBC URL cannot be null or empty\");\n    }\n\n    String actualUrl = extractHttpUrl(jdbcUrl);\n\n    try {\n      URI uri = new URI(actualUrl);\n\n      validateScheme(uri.getScheme());\n      String host = validateAndGetHost(uri.getHost(), jdbcUrl);\n      int port = getPortOrDefault(uri.getPort(), uri.getScheme());\n\n      String clickHouseUrl = String.format(\"%s://%s:%d\", uri.getScheme(), host, port);\n      String database = extractDatabase(uri.getPath());\n      Properties properties = extractProperties(uri.getQuery());\n\n      return new ParsedJdbcUrl(clickHouseUrl, database, properties);\n\n    } catch (URISyntaxException e) {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/clickhouse/src/main/java/org/apache/beam/sdk/io/clickhouse/ClickHouseJdbcUrlParser.java#L74-L110","documentation":"ClickHouseJdbcUrlParser.parse validates its input before attempting URI extraction: a null or empty JDBC URL cannot yield an HTTP endpoint or database name, so it throws IllegalArgumentException immediately. This is the first guard in the parse pipeline that converts jdbc:clickhouse:... URLs into an HTTP URL, database, and properties.","triggerScenarios":"Calling parse(null), parse(\"\"), or passing a URL field that was never populated — e.g., an unset pipeline option, a config object whose url property defaulted to null, or a builder where the connection string is supplied after parse is invoked.","commonSituations":"Missing JDBC URL in job options/environment config; pipeline options not wired to the IO writer; empty string from a templated config in CI/CD; refactors that changed the option name so the old one reads as null.","solutions":["Supply a non-empty JDBC URL of the form jdbc:clickhouse://host:port/database[?params]","Check the pipeline option/config source that should contain the URL — it is null or empty at runtime","Validate the URL before constructing the IO transform"],"exampleFix":"// before\nClickHouseIO.<Row>write(options.getJdbcUrl(), table) // getJdbcUrl() == \"\"\n// after\nClickHouseIO.<Row>write(\"jdbc:clickhouse://localhost:8123/default\", table)","handlingStrategy":"validation","validationCode":"if (jdbcUrl == null || jdbcUrl.isEmpty()) {\n  throw new IllegalArgumentException(\"jdbcUrl must be configured (jdbc:clickhouse://host:port/db)\");\n}\nif (!jdbcUrl.startsWith(\"jdbc:clickhouse:\")) {\n  throw new IllegalArgumentException(\"Not a ClickHouse JDBC URL: \" + jdbcUrl);\n}","typeGuard":"static boolean isNonEmptyString(String s) {\n  return s != null && !s.trim().isEmpty();\n}","tryCatchPattern":"try {\n  ClickHouseJdbcUrlParser.parse(jdbcUrl);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"cannot be null or empty\")) { /* fail fast with config guidance */ }\n  throw e;\n}","preventionTips":["Validate required pipeline options (JDBC URL) at job startup, before expansion","Use defaults or fail-fast checks so templated configs never yield empty URLs","Keep option names stable; rename checks when refactoring config keys"],"tags":["java","clickhouse","jdbc","url","null-argument"],"backgroundTag":"missing-required-config-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}