apache/seatunnel · error · JobDefineCheckException

Duplicated transform name '%s'. Transform names must be uniq

Error message

Duplicated transform name '%s'. Transform names must be unique within a job.

What it means

Thrown by parseTransform when a transform explicitly sets a 'name' (plugin_name-level name option) that duplicates a name already used by another transform in the same job. Transform names are used to build the DAG and connect edges, so they must be unique within a job.

Source

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

        int spareParallelism = inputs.get(0)._2().getParallelism();
        int parallelism =
                DryRunSampleConfig.isEnabled(jobConfig.getEnvOptions())
                        ? 1
                        : readonlyConfig
                                .getOptional(EnvCommonOptions.PARALLELISM)
                                .orElse(spareParallelism);
        SeaTunnelTransform<?> transform =
                FactoryUtil.createAndPrepareMultiTableTransform(
                        new ArrayList<>(catalogTables), readonlyConfig, classLoader, factoryId);

        transform.setJobContext(jobConfig.getJobContext());
        long id = idGenerator.getNextId();
        String legacyActionName = JobConfigParser.createTransformActionName(index, factoryId);
        String actionName = legacyActionName;
        String configuredName = getOptionalName(config);
        if (StringUtils.isNotBlank(configuredName)) {
            if (!usedTransformNames.add(configuredName)) {
                throw new JobDefineCheckException(
                        String.format(
                                "Duplicated transform name '%s'. Transform names must be unique within a job.",
                                configuredName));
            }
            actionName = configuredName;
        }

        TransformAction transformAction =
                new TransformAction(
                        id,
                        actionName,
                        new ArrayList<>(inputActions),
                        transform,
                        jarUrls,
                        new HashSet<>());
        transformAction.setParallelism(parallelism);

        List<Tuple2<CatalogTable, Action>> actions = new ArrayList<>();

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Give each transform a distinct name option value.
  2. If names are not needed for edges, remove the name option so the parser uses the auto-generated legacy action name.
  3. Check copy-pasted transform blocks for duplicated names.

Example fix

// before
transform {
  Sql { name = "t1" ... }
  Sql { name = "t1" ... }
}
// after
transform {
  Sql { name = "filter-orders" ... }
  Sql { name = "enrich-users" ... }
}
Defensive patterns

Strategy: validation

Validate before calling

Set<String> names = new HashSet<>();
for (TransformConfig t : transforms) {
  String n = t.getName();
  if (n != null && !names.add(n)) throw new IllegalArgumentException("Duplicate transform name: " + n);
}

Try / catch

try {
  engine.submitJob(config);
} catch (JobDefineCheckException e) {
  if (e.getMessage().startsWith("Duplicated transform name")) {
    // rename the offending transform's name option and resubmit
  }
}

Prevention

When it happens

Trigger: Two or more transform blocks in one job config both define the same non-blank name via getOptionalName(config) (the transform's name option), during parseTransforms.

Common situations: Copy-pasting a transform block (e.g. two SQL or FieldMapper transforms) and forgetting to change its name; generated configs templated without unique names.

Related errors


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