apache/seatunnel · error · IllegalStateException

No actions define in the job. Cannot execute.

Error message

No actions define in the job. Cannot execute.

What it means

The LogicalDagGenerator constructor rejects a job whose action list is empty: a DAG with no actions cannot be planned or executed, so it fails fast with an IllegalStateException during logical DAG construction. This is an upstream invariant — a valid parsed job must contain at least one source/sink/transform action.

Source

Thrown at seatunnel-engine/seatunnel-engine-core/src/main/java/org/apache/seatunnel/engine/core/dag/logical/LogicalDagGenerator.java:68

    public LogicalDagGenerator(
            @NonNull List<Action> actions,
            @NonNull JobConfig jobConfig,
            @NonNull IdGenerator idGenerator) {
        this(actions, jobConfig, idGenerator, false);
    }

    public LogicalDagGenerator(
            @NonNull List<Action> actions,
            @NonNull JobConfig jobConfig,
            @NonNull IdGenerator idGenerator,
            boolean isStartWithSavePoint) {
        this.actions = actions;
        this.jobConfig = jobConfig;
        this.idGenerator = idGenerator;
        this.isStartWithSavePoint = isStartWithSavePoint;
        if (actions.isEmpty()) {
            throw new IllegalStateException("No actions define in the job. Cannot execute.");
        }
    }

    public LogicalDag generate() {
        actions.forEach(this::createLogicalVertex);
        Set<LogicalEdge> logicalEdges = createLogicalEdges();
        LogicalDag logicalDag = new LogicalDag(jobConfig, idGenerator);
        logicalDag.getEdges().addAll(logicalEdges);
        logicalDag.getLogicalVertexMap().putAll(logicalVertexMap);
        logicalDag.setStartWithSavePoint(isStartWithSavePoint);
        return logicalDag;
    }

    private void createLogicalVertex(Action action) {
        final Long logicalVertexId = action.getId();
        if (logicalVertexMap.containsKey(logicalVertexId)) {
            return;
        }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check the job config file contains at least one valid source and sink block (env, source, transform, sink sections).
  2. Run the config through the SeaTunnel config parser / 'seatunnel.sh --config ... -m local' to see earlier parse errors that silently dropped actions.
  3. If submitting programmatically, verify your built List<Action> passed to the planner is non-empty before creating LogicalDagGenerator.
  4. If restoring from a savepoint, confirm the original job had actions and the savepoint state is not empty/corrupted.

Example fix

# before (empty job)
env { parallelism = 1 }
# after
env { parallelism = 1 }
source { FakeSource { plugin_output = "fake" } }
sink { Console {} }
Defensive patterns

Strategy: validation

Validate before calling

if (config.getPluginConfigs().isEmpty()) throw new IllegalArgumentException("job config must define at least one source and sink");

Try / catch

try { jobClient.executeJob(config); } catch (IllegalStateException e) { if (e.getMessage().contains("No actions")) { log.error("job config produced no actions; check source/sink blocks"); } throw e; }

Prevention

When it happens

Trigger: Constructing new LogicalDagGenerator(Collections.emptyList(), jobConfig, idGenerator, isStartWithSavePoint) — reached when a submitted job's plan produced zero actions, e.g. an empty or malformed job config graph.

Common situations: Job config file missing the source/sink sections; all plugins filtered out by an upstream parse bug; submitting an empty config to the Zeta REST/job submission client; a savepoint restore path that drops all actions.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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