apache/seatunnel · error · SeaTunnelRuntimeException

Table URL cannot be null or empty

Error message

Table URL cannot be null or empty

What it means

SeaTunnelRuntimeException (ERROR_INVALID_TABLE_URL) thrown by GravitinoClient.getTableSchemaPath when the supplied schemaHttpUrl is null or empty. A URL is mandatory to parse out catalog, schema, and table names.

Source

Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/metalake/gravitino/GravitinoClient.java:103

    public JsonNode getMetaInfo(String sourceId, String metalakeUrl) throws IOException {
        if (!metalakeUrl.endsWith("/")) {
            metalakeUrl = metalakeUrl + "/";
        }
        JsonNode rootNode = executeGetRequest(metalakeUrl + sourceId);
        JsonNode catalogNode = getRequiredNode(rootNode, JSON_FIELD_CATALOG);
        return getRequiredNode(catalogNode, JSON_FIELD_PROPERTIES);
    }

    @Override
    public JsonNode getTableSchema(String schemaHttpUrl) throws IOException {
        JsonNode rootNode = executeGetRequest(schemaHttpUrl);
        return getRequiredNode(rootNode, JSON_FIELD_TABLE);
    }

    @Override
    public TablePath getTableSchemaPath(String schemaHttpUrl) {
        if (schemaHttpUrl == null || schemaHttpUrl.isEmpty()) {
            throw new SeaTunnelRuntimeException(
                    ERROR_INVALID_TABLE_URL, "Table URL cannot be null or empty");
        }
        final Matcher matcher = getMatcher(schemaHttpUrl);
        String catalogName = matcher.group(1);
        String schemaName = matcher.group(2);
        String tableName = matcher.group(3);
        return TablePath.of(catalogName, schemaName, tableName);
    }

    private Matcher getMatcher(String schemaHttpUrl) {
        Matcher matcher = TABLE_URL_PATTERN.matcher(schemaHttpUrl);
        if (!matcher.find()) {
            throw new SeaTunnelRuntimeException(
                    ERROR_INVALID_TABLE_URL,
                    String.format(
                            "Invalid table URL format: '%s'. "
                                    + "Expected format: http://host/api/metalakes/{metalake}/catalogs/{catalog}/schemas/{schema}/tables/{table}",
                            schemaHttpUrl));

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure a non-empty Gravitino table URL is produced before calling getTableSchemaPath.
  2. Check the upstream call/configuration that supplies the URL for null/empty results.
  3. Fail fast with your own validation and a clear message pointing to the missing config value.

Example fix

// before
TablePath path = client.getTableSchemaPath(url);
// after
if (url == null || url.isEmpty()) {
    throw new IllegalArgumentException("tableUrl config is empty");
}
TablePath path = client.getTableSchemaPath(url);
Defensive patterns

Strategy: validation

Validate before calling

if (tableUrl == null || tableUrl.trim().isEmpty()) {
    throw new IllegalArgumentException("tableUrl must be set to the Gravitino table URL");
}

Type guard

static boolean hasText(String s) { return s != null && !s.trim().isEmpty(); }
// if (hasText(tableUrl)) { client.getTableSchemaPath(tableUrl); }

Try / catch

try {
    return client.getTableSchemaPath(url);
} catch (SeaTunnelRuntimeException e) {
    if ("Table URL cannot be null or empty".equals(e.getMessage())) {
        throw new IllegalStateException("Missing tableUrl config for table lookup");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getTableSchemaPath(null) or getTableSchemaPath("") — e.g. when an upstream step that was supposed to produce the table's HTTP URL silently returned null or an empty string.

Common situations: Upstream metadata lookup returned no URL for the table; configuration field left blank; a variable holding the URL was never initialized before being passed in.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/354ab5d145cbf5cb. Report an issue: GitHub.