apache/seatunnel · error · IllegalArgumentException
Refusing write without --yes
Error message
Refusing write without --yes
What it means
After passing the write guard and counting affected rows, runWalPurgeAcked performs the actual DELETE only when --yes is set. If rows matched the cutoff but the user has not confirmed with --yes (and was not in --dry-run, which returned earlier), the command throws IllegalArgumentException instead of mutating the database.
Solutions
- Re-run the command with --yes to authorize the deletion.
- Run with --dry-run first to see how many ACKED rows would be deleted, then confirm with --yes.
- In programmatic callers, set yes=true only after the operator has confirmed.
Example fix
// before agent db wal-purge-acked --older-than-ms 86400000 // after agent db wal-purge-acked --older-than-ms 86400000 --yes
Defensive patterns
Strategy: validation
Validate before calling
# bash wrapper: confirm before non-dry-run purge if [[ " $* " != *' --yes '* && " $* " != *' --dry-run '* ]]; then read -p "Apply wal-purge-acked? Type YES: " c && [[ $c == YES ]] && set -- "$@" --yes fi
Try / catch
try {
walPurgeAcked(cli);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("--yes")) {
log.info("Purge not applied; run again with --yes after reviewing --dry-run output");
}
} Prevention
- Preview with --dry-run (which prints the row count) before every real purge.
- Gate scripts on the count from --dry-run before adding --yes.
- Keep the guard in place in programmatic Cli construction — set yes only after explicit confirmation.
When it happens
Trigger: Running wal-purge-acked with --yes omitted while at least one ACKED row matches the cutoff; programmatic invocation with a Cli options object whose isYes() is false.
Common situations: Programmatic callers constructing a Cli with dry-run=false but yes unset; users whose earlier zero-row runs never reached the write step, then hit this once rows exist.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- Write operations require --yes (or use --dry-run)
- Agent is running (pid file ); stop the agent before write…
- Cluster name is required. Please specify it using -cn or…
- cluster: is not running, Please start the cluster first.
- Dry-run is only supported via CLI
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/4b533735c7ed9ef9.
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:336
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 =
db.getConnection().prepareStatement(EdgeAgentDbSql.WAL_PURGE_ACKED_BEFORE)) {
statement.setString(1, WalRecordStatus.ACKED.name());
statement.setLong(2, cutoff);
int deleted = statement.executeUpdate();
System.out.println(
"Deleted " + deleted + " ACKED rows (updated_at < " + cutoff + ")");
}
}
}
private long countAckedBefore(EdgeAgentDbConnection db, long cutoff) throws SQLException {
try (PreparedStatement statement =
db.getConnection().prepareStatement(EdgeAgentDbSql.WAL_COUNT_ACKED_BEFORE)) {
statement.setString(1, WalRecordStatus.ACKED.name());
statement.setLong(2, cutoff);
try (ResultSet rs = statement.executeQuery()) {View on GitHub (pinned to cf67b549a7)