conductor-oss/conductor · error · IllegalArgumentException
pruneExecutions: olderThanDays must be >= 1, got ${olderThan
Error message
pruneExecutions: olderThanDays must be >= 1, got ${olderThanDays} What it means
Thrown by AgentService.computePruneCutoffEpochMs when olderThanDays is less than 1. This guard exists because non-positive values would place the cutoff in the future, matching every terminal execution and causing mass data deletion (documented in issue #1331). The method computes now.minus(olderThanDays, DAYS) and clamps to >= 0. IllegalArgumentException maps to HTTP 400.
Source
Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/AgentService.java:605
workflowService.deleteWorkflow(executionId, archiveTasks);
}
/**
* Computes the prune cutoff, guarding the two ways an unchecked {@code olderThanDays} turned
* the prune into a data-loss operation (issue #1331): non-positive values put the cutoff in the
* future (matching every terminal execution), and very large values push the computed epoch
* negative, which the search backend matched against recent executions. A cutoff clamped to
* epoch start matches nothing, which is the correct meaning of "older than anything that
* exists".
*
* @param olderThanDays minimum age in days, must be >= 1
* @param now the current instant
* @return cutoff in epoch milliseconds, never negative
*/
@VisibleForTesting
static long computePruneCutoffEpochMs(int olderThanDays, Instant now) {
if (olderThanDays < 1) {
throw new IllegalArgumentException(
"pruneExecutions: olderThanDays must be >= 1, got " + olderThanDays);
}
return Math.max(0L, now.minus(olderThanDays, ChronoUnit.DAYS).toEpochMilli());
}
/**
* Bulk-delete completed execution records older than {@code olderThanDays} days.
*
* <p>Searches for COMPLETED, FAILED, TERMINATED, and TIMED_OUT executions whose end time is
* before the cutoff, then removes them from the DB in batches.
*
* @param olderThanDays minimum age in days for executions to be pruned
* @param archiveTasks if true, archive task records instead of deleting
* @return number of executions deleted
*/
public int pruneExecutions(int olderThanDays, boolean archiveTasks) {
long cutoffEpochMs = computePruneCutoffEpochMs(olderThanDays, Instant.now());
String[] terminalStatuses = {"COMPLETED", "FAILED", "TERMINATED", "TIMED_OUT"};View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Pass olderThanDays >= 1 — use a sensible retention like 30 or 90.
- If the intent is aggressive cleanup, use 1 (the minimum) rather than 0.
- Validate the input at the CLI/API boundary before forwarding to pruneExecutions.
Example fix
// before agentService.pruneExecutions(0, false); // -> error // after int days = Math.max(1, configuredRetentionDays); agentService.pruneExecutions(days, false);
Defensive patterns
Strategy: validation
Validate before calling
if (olderThanDays < 1) {
throw new IllegalArgumentException(
"Retention must be at least 1 day, got " + olderThanDays);
}
agentService.pruneExecutions(olderThanDays, archiveTasks); Prevention
- Never pass 0 or negative days to pruneExecutions — this guard prevents accidental mass deletion.
- Set a sensible default retention (30/60/90 days) in configuration.
- Validate the value at the CLI/API boundary before forwarding.
When it happens
Trigger: Calling pruneExecutions(0, ...) or pruneExecutions(-1, ...); a CLI/API caller passes olderThanDays=0 intending 'delete everything now' not realizing the guard rejects it; a default value of 0 is used when the parameter is omitted.
Common situations: Operator misinterprets 0 as 'no minimum age'; configuration template has an unset default that resolves to 0; automated cleanup job receives a computed days value that underflows to 0 or negative.
Related errors
- inspectPlan: agentConfig is required
- inspectPlan: plan is required
- inspectPlan: agentConfig.strategy must be 'plan_execute', go
- Start request is required
- Agent execution requires a non-empty prompt, at least one me
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/45c349b569d09f7b.
Report an issue: GitHub.