apache/seatunnel · error · ParserException

The SQL config must contain at least one source table

Error message

The SQL config must contain at least one source table

What it means

After parsing all statements, SqlConfigBuilder requires at least one table whose 'type' option is 'source'; if sourceConfigs is empty it throws ParserException. Every job needs at least one source table to read from.

Source

Thrown at seatunnel-config/seatunnel-config-sql/src/main/java/org/apache/seatunnel/config/sql/SqlConfigBuilder.java:155

            }

            // filter out the sink config without 'plugin_input' option
            seaTunnelConfig.setSinkConfigs(
                    seaTunnelConfig.getSinkConfigs().stream()
                            .filter(
                                    sinkConfig -> {
                                        boolean containSourceTable = false;
                                        for (Option option : sinkConfig.getOptions()) {
                                            if (option.getKey().equals(OPTION_PLUGIN_INPUT_KEY)) {
                                                containSourceTable = true;
                                                break;
                                            }
                                        }
                                        return containSourceTable;
                                    })
                            .collect(Collectors.toList()));
            if (seaTunnelConfig.getSourceConfigs().isEmpty()) {
                throw new ParserException("The SQL config must contain at least one source table");
            }
            if (seaTunnelConfig.getSinkConfigs().isEmpty()) {
                throw new ParserException(
                        "The SQL config must contain `INSERT INTO ... SELECT ...` syntax");
            }

            // render to hocon config
            String configContent = ConfigTemplate.generate(seaTunnelConfig);
            log.debug("Generated config: \n{}", configContent);
            return ConfigFactory.parseString(configContent);
        } catch (ParserException e) {
            throw e;
        } catch (Exception e) {
            throw new ParserException(e);
        }
    }

    private static List<String> parseAnnoConfigAndSqlLine(

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Add a CREATE TABLE ... WITH ('connector'='...', 'type'='source') for the read-side table.
  2. Verify the type option value is exactly 'source' (case-insensitive).
  3. Ensure the INSERT's SELECT references the declared source table by name.
  4. Check the source table wasn't parsed as a sink due to a wrong 'type' value.

Example fix

// before
CREATE TABLE sink WITH ('connector'='console', 'type'='sink') (id INT);
INSERT INTO sink SELECT id FROM src; -- src never declared
// after
CREATE TABLE src WITH ('connector'='fake', 'type'='source') (id INT);
CREATE TABLE sink WITH ('connector'='console', 'type'='sink') (id INT);
INSERT INTO sink SELECT id FROM src;
Defensive patterns

Strategy: validation

Validate before calling

boolean hasSource = Files.readAllLines(sqlFile).stream()
    .anyMatch(l -> l.contains("'type'='source'") || l.contains("'type' = 'source'"));

Try / catch

try { Config c = SqlConfigBuilder.of(sqlFile); } catch (ParserException e) { if (e.getMessage().contains("at least one source")) { /* add source table and retry */ } }

Prevention

When it happens

Trigger: The .sql file defines only sink tables (CREATE TABLE ... WITH ('type'='sink')) plus an INSERT whose SELECT reads from tables never declared as sources.

Common situations: Forgetting the 'type'='source' option on the source CREATE TABLE, mistyping it ('Source', 'src'), SELECTing against a table never created, or sources being misclassified due to wrong 'type' values.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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