apache/seatunnel · error · IllegalArgumentException

source position partition must not be blank

Error message

source position partition must not be blank

What it means

SqliteSourcePositionStore.save() requires a non-blank partition value; the (sourceId, partition) pair is the upsert key for positions. A null or whitespace-only partition cannot identify which split/offset the row tracks, so save() throws this IllegalArgumentException.

Solutions

  1. Provide a partition identifier on the EdgeSourcePosition before saving (use a sentinel like "default" if the source is single-partition).
  2. Fix the source's split/partition naming so every split carries a stable, non-empty partition string.
  3. Validate the position object in caller code before invoking save().
  4. Verify the upstream position deserialization preserves the partition field.

Example fix

// before
store.save(new EdgeSourcePosition(sourceId, null, offset, 0));
// after
store.save(new EdgeSourcePosition(sourceId, "partition-0", offset, 0));
Defensive patterns

Strategy: validation

Validate before calling

if (position.getPartition() == null || position.getPartition().trim().isEmpty()) { position = position.withPartition("default"); } store.save(position);

Type guard

boolean hasPartition(EdgeSourcePosition p) { return p.getPartition() != null && !p.getPartition().trim().isEmpty(); }

Try / catch

try { store.save(position); } catch (IllegalArgumentException e) { if (e.getMessage().contains("partition must not be blank")) { log.error("Position missing partition: {}", position); } throw e; }

Prevention

When it happens

Trigger: Calling positionStore.save(position) with EdgeSourcePosition whose getPartition() is null or blank — e.g. a source that reports no partition identifier for its splits.

Common situations: Connector implementations that do not assign partition identifiers to splits; migrating positions from another store that omitted partition; constructing positions programmatically without the partition field.

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

Appendix: source

Thrown at seatunnel-edge-agent/seatunnel-edge-agent-starter/src/main/java/org/apache/seatunnel/edge/agent/starter/wal/sqlite/SqliteSourcePositionStore.java:92

            try (ResultSet resultSet = statement.executeQuery()) {
                while (resultSet.next()) {
                    EdgeSourcePosition position = toPosition(resultSet);
                    positions.put(position.getPartition(), position);
                }
            }
        }
        return positions;
    }

    @Override
    public void save(EdgeSourcePosition position) throws Exception {
        String sourceId = position.getSourceId();
        String partition = position.getPartition();
        if (sourceId == null || sourceId.trim().isEmpty()) {
            throw new IllegalArgumentException("source position sourceId must not be blank");
        }
        if (partition == null || partition.trim().isEmpty()) {
            throw new IllegalArgumentException("source position partition must not be blank");
        }
        long updatedAt =
                position.getUpdatedAt() > 0L ? position.getUpdatedAt() : System.currentTimeMillis();
        try (PreparedStatement statement =
                connection.prepareStatement(SourcePositionSqlStatements.UPSERT)) {
            statement.setString(1, sourceId);
            statement.setString(2, partition);
            statement.setLong(3, position.getOffset());
            statement.setBytes(4, MetadataSerde.serialize(position.getMetadata()));
            statement.setLong(5, updatedAt);
            statement.executeUpdate();
        }
    }

    @Override
    public void close() throws SQLException {
        if (closeConnection) {
            connection.close();

View on GitHub (pinned to cf67b549a7)