apache/seatunnel · error · JobDefineCheckException

Sink don't support simultaneous writing of data from…

Error message

Sink don't support simultaneous writing of data from multi-table source and other sources.

What it means

parseSink rejects a sink whose multiple input vertices include one that is itself a multi-table (catalog-table, action list with >1 entries) input. SeaTunnel only supports a sink either writing from a single multi-table source stream or from regular single-table inputs, not both mixed together.

Solutions

  1. Split into separate sinks: one sink consuming the multi-table source and another sink for the other source.
  2. Use union-style transforms per structure, keeping multi-table sources isolated on their own branch.
  3. Restrict multi-table source matching (table_names/table_path) so only one table flows into the mixed sink if merging is intended.

Example fix

// before: one sink with mixed inputs
sink { Jdbc { ... } }
// after: two independent sinks
sink { Jdbc { ... /* fed by multi-table source */ } }
sink { Console { ... /* fed by the other source */ } }
Defensive patterns

Strategy: validation

Validate before calling

// don't mix a multi-table source with other inputs on one sink
boolean multiTable = sourceTables.size() > 1;
if (multiTable && sinkInputs.size() > 1) {
  throw new IllegalArgumentException("Sink cannot combine multi-table source with other inputs");
}

Try / catch

try {
  engine.submitJob(config);
} catch (JobDefineCheckException e) {
  if (e.getMessage().contains("multi-table source and other sources")) {
    // split into separate sink branches
  }
}

Prevention

When it happens

Trigger: During parse(), a sink references more than one input vertex in the DAG and at least one of those vertices carries more than one (CatalogTable, Action) pair, i.e. combines multi-table source output with another source/transform.

Common situations: A config that unions a multi-table source (table_path matching many tables) with a second source into one sink; wiring multiple parents into one sink node in HOCON graph syntax.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-engine/seatunnel-engine-core/src/main/java/org/apache/seatunnel/engine/core/parse/MultipleTableJobConfigParser.java:646

            ClassLoader classLoader,
            LinkedHashMap<String, List<Tuple2<CatalogTable, Action>>> tableWithActionMap) {

        ReadonlyConfig readonlyConfig = ReadonlyConfig.fromConfig(sinkConfig);
        String factoryId = getFactoryId(readonlyConfig);
        List<String> inputIds = getInputIds(readonlyConfig);

        List<List<Tuple2<CatalogTable, Action>>> inputVertices =
                inputIds.stream()
                        .map(tableWithActionMap::get)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
        if (inputVertices.isEmpty()) {
            // Tolerates incorrect configuration of simple graph
            inputVertices = Collections.singletonList(findLast(tableWithActionMap));
        } else if (inputVertices.size() > 1) {
            for (List<Tuple2<CatalogTable, Action>> inputVertex : inputVertices) {
                if (inputVertex.size() > 1) {
                    throw new JobDefineCheckException(
                            "Sink don't support simultaneous writing of data from multi-table source and other sources.");
                }
            }
        }

        // get jar urls
        Set<URL> jarUrls = new HashSet<>();
        if (!DryRunSampleConfig.isEnabled(jobConfig.getEnvOptions())) {
            jarUrls.addAll(getSinkPluginJarPaths(sinkConfig));
        }
        List<SinkAction<?, ?, ?, ?>> sinkActions = new ArrayList<>();
        int failedTableStartIndex = failedTables.size();

        // union
        if (inputVertices.size() > 1) {
            Set<Action> inputActions =
                    inputVertices.stream()
                            .flatMap(Collection::stream)

View on GitHub (pinned to cf67b549a7)