apache/seatunnel · error · ConfigCheckException

${location(SINK, configIndex, factoryId)} does not support w

Error message

${location(SINK, configIndex, factoryId)} does not support writing both a multi-table source and other sources.

What it means

DryRunConnectValidator.resolveSinkInputTables rejects a sink that receives more than one upstream input when at least one of those inputs is itself a multi-table source (its SchemaInfo holds multiple CatalogTables). Mixing a multi-table source with other inputs would require per-table routing the sink topology does not support in this validation path, so a ConfigCheckException is thrown naming the offending sink.

Source

Thrown at seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/command/DryRunConnectValidator.java:368

                            PluginType.SINK,
                            configIndex,
                            factoryId,
                            "connector dry-run connection validation passed"));
        } catch (Exception e) {
            throw wrap(PluginType.SINK, configIndex, factoryId, e);
        }
    }

    /**
     * Flattens sink input vertices to the catalog tables the sink must accept, enforcing the same
     * multi-input constraints as the runtime parser.
     */
    private List<CatalogTable> resolveSinkInputTables(
            List<SchemaInfo> inputVertices, int configIndex, String factoryId) {
        if (inputVertices.size() > 1) {
            for (SchemaInfo inputVertex : inputVertices) {
                if (inputVertex.getCatalogTables().size() > 1) {
                    throw new ConfigCheckException(
                            location(PluginType.SINK, configIndex, factoryId)
                                    + " does not support writing both a multi-table source and other sources.");
                }
            }
            List<CatalogTable> mergedInputs =
                    inputVertices.stream()
                            .map(SchemaInfo::getCatalogTables)
                            .flatMap(Collection::stream)
                            .collect(Collectors.toList());
            checkCatalogTableTypesEqual(mergedInputs, PluginType.SINK, configIndex, factoryId);
            return Collections.singletonList(mergedInputs.get(0));
        }
        return inputVertices.get(0).getCatalogTables();
    }

    /**
     * Returns true only when the config declares a schema that actually defines columns, mirroring
     * the non-placeholder branches of {@code TableSchemaDiscoverer}. A bare {@code schema} block

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Give the multi-table source its own dedicated sink, and wire other inputs to a separate sink.
  2. Reduce the multi-table source to a single table so it can be merged with other inputs.
  3. Insert a transform that consolidates schemas if merging is truly intended, ensuring a single upstream for the sink.

Example fix

// before
sink {
  Console {
    plugin_input = [multi_table_source, other_source]
  }
}
// after
sink {
  Console { plugin_input = multi_table_source }
  Console { plugin_input = other_source }
}
Defensive patterns

Strategy: validation

Validate before calling

// before validating, ensure a sink with multiple plugin_input values has no multi-table source upstream
const multiTableOutputs = sources.filter(s => s.catalogTables.length > 1).map(s => s.id);
const badSink = sinks.find(k => inputsOf(k).length > 1 && inputsOf(k).some(i => multiTableOutputs.includes(i)));
if (badSink) throw new Error("Sink " + badSink.id + " mixes a multi-table source with other inputs");

Try / catch

try { validateConf(conf, DryRun.CONNECT); } catch (ConfigCheckException e) { if (e.getMessage().contains("does not support writing both a multi-table source")) { splitSinkWiring(conf); } else { throw e; } }

Prevention

When it happens

Trigger: A dry-run CONNECT validation of a config where a sink declares multiple 'plugin_input' upstreams and one upstream is a source that expanded into multiple catalog tables (multi-table source such as a pattern-matched table list), while other upstreams are single-table sources or transforms.

Common situations: Wiring a multi-table source (e.g. MySQL CDC matching many tables) together with additional sources/transforms into one sink; copying DAG wiring from a single-table job into a multi-table job.

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/5ff0b39054955ae2. Report an issue: GitHub.