apache/seatunnel · error · IllegalArgumentException

wal-purge-acked requires --older-than-ms <positive-ms>

Error message

wal-purge-acked requires --older-than-ms <positive-ms>

What it means

runWalPurgeAcked purges ACKED WAL rows older than a cutoff computed as now minus --older-than-ms. A zero or negative value would make the cutoff nonsensical or purge rows from now forward, so the command requires a strictly positive millisecond duration and throws IllegalArgumentException otherwise.

Solutions

  1. Re-run with a positive duration, e.g. wal-purge-acked --older-than-ms 86400000 (24h).
  2. Fix the script default: OLDER_THAN_MS=${OLDER_THAN_MS:-86400000}.
  3. Remember there is no default; the flag is mandatory. Run with --dry-run first to preview the row count.

Example fix

// before
agent db wal-purge-acked --yes
// after
agent db wal-purge-acked --older-than-ms 86400000 --yes
Defensive patterns

Strategy: validation

Validate before calling

OLDER_THAN_MS=${OLDER_THAN_MS:-86400000}
if ! [[ "$OLDER_THAN_MS" =~ ^[0-9]+$ ]] || [ "$OLDER_THAN_MS" -le 0 ]; then
  echo "--older-than-ms must be a positive integer" >&2; exit 2
fi

Try / catch

try {
  runWalPurgeAcked();
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("--older-than-ms")) {
    System.err.println("Pass a positive duration in ms, e.g. --older-than-ms 86400000 (24h)");
  }
}

Prevention

When it happens

Trigger: Running `agent db wal-purge-acked` without --older-than-ms, or with --older-than-ms 0 or a negative value; a script passing an unset variable that evaluates to 0.

Common situations: Users omit the flag assuming a default retention window exists; automation passes ${RETENTION_MS} which is unset; confusion between seconds and milliseconds producing 0.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-edge-agent/seatunnel-edge-agent-starter/src/main/java/org/apache/seatunnel/edge/agent/starter/command/db/EdgeAgentDbCommand.java:320

                new MutationBind(now, WalRecordStatus.PENDING.name()),
                "RESET DEAD -> PENDING");
    }

    private void runWalUnstickSending() throws Exception {
        DbWriteGuard.requireWriteAllowed(paths, cli);
        long now = System.currentTimeMillis();
        executeStatusMutation(
                WalRecordStatus.SENDING.name(),
                EdgeAgentDbSql.WAL_COUNT_BY_STATUS_FILTER,
                EdgeAgentDbSql.WAL_UNSTICK_SENDING,
                new MutationBind(now, WalRecordStatus.PENDING.name()),
                "RESET SENDING -> PENDING");
    }

    private void runWalPurgeAcked() throws Exception {
        DbWriteGuard.requireWriteAllowed(paths, cli);
        if (cli.getOlderThanMs() <= 0L) {
            throw new IllegalArgumentException(
                    "wal-purge-acked requires --older-than-ms <positive-ms>");
        }
        long cutoff = System.currentTimeMillis() - cli.getOlderThanMs();
        try (EdgeAgentDbConnection db =
                EdgeAgentDbConnection.openReadWrite(paths.getSqlitePath())) {
            long count = countAckedBefore(db, cutoff);
            if (cli.isDryRun()) {
                System.out.println(
                        "DRY-RUN: would delete "
                                + count
                                + " ACKED rows with updated_at < "
                                + cutoff);
                return;
            }
            if (!cli.isYes()) {
                throw new IllegalArgumentException("Refusing write without --yes");
            }
            try (PreparedStatement statement =

View on GitHub (pinned to cf67b549a7)