apache/seatunnel · error · ParserException
The SQL config must contain `INSERT INTO ... SELECT ...` syn
Error message
The SQL config must contain `INSERT INTO ... SELECT ...` syntax
What it means
SqlConfigBuilder requires at least one sink config, produced only by INSERT statements; if sinkConfigs is empty after parsing it throws ParserException telling the user the config must contain `INSERT INTO ... SELECT ...` syntax. A job that only declares tables but never inserts is invalid.
Source
Thrown at seatunnel-config/seatunnel-config-sql/src/main/java/org/apache/seatunnel/config/sql/SqlConfigBuilder.java:158
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(
List<String> lines, SeaTunnelConfig seaTunnelConfig) {
List<String> sqlLines = new ArrayList<>();
List<String> annotationConfigs = new ArrayList<>();View on GitHub (pinned to cf67b549a7)
Solutions
- Add an INSERT INTO <sink_table> SELECT ... FROM <source_table> statement.
- Verify the INSERT parses correctly as a JSqlParser Insert (no exotic syntax).
- Ensure the sink CREATE TABLE exists and its name matches the INSERT target.
- Check plugin_input/plugin_output identifiers line up so the sink isn't filtered out.
Example fix
// before
CREATE TABLE src WITH ('connector'='fake', 'type'='source') (id INT);
-- no insert: job has no sink
// 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 hasInsert = Files.readAllLines(sqlFile).stream().anyMatch(l -> l.trim().toUpperCase().startsWith("INSERT INTO")); Try / catch
try { Config c = SqlConfigBuilder.of(sqlFile); } catch (ParserException e) { if (e.getMessage().contains("INSERT INTO")) { /* add an INSERT statement */ } } Prevention
- Every job needs INSERT INTO sink SELECT ... FROM source
- Keep sink table name identical to the INSERT target
- Check plugin_input/plugin_output wiring so sinks aren't filtered
- Lint for INSERT presence before submission
When it happens
Trigger: The .sql file contains only CREATE TABLE statements (sources and/or intermediate tables) with no INSERT INTO ... SELECT statement.
Common situations: Authoring only schema definitions expecting seatunnel to auto-wire, INSERT statements that failed the instanceof Insert check due to syntax quirks, or the sink filtered out because its plugin_input didn't match.
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
- The SQL config must contain at least one source table
- Table name duplicate: %s
- Failed to parse job config file: <path>
- Failed to parse job config:
- Unsupported SQL syntax: %s
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/7340cec17cd3bc5e.
Report an issue: GitHub.