iflytek/astron-agent · warning · BusinessException

PARAMS_ERROR

PARAMS_ERROR

Error message

cron has no future fire time

What it means

In the cron preview, when the cron expression yields no next fire time after the current instant (cron.next(cursor) returns null), the service throws BusinessException(PARAMS_ERROR, "cron has no future fire time"). This happens for expressions whose schedule is entirely in the past or structurally cannot fire again.

Solutions

  1. Correct the cron expression so it recurs or points to a future date; validate it with a cron parser before saving.
  2. Remove the explicit year field or use wildcards so the schedule repeats.
  3. Check the time zone used for preview; an expression valid in another zone may be exhausted in this one.

Example fix

// before
String cron = "0 0 9 1 1 ? 2024"; // already past
automationService.preview(flowId, cron);
// after
String cron = "0 0 9 1 1 ? *"; // recurs every Jan 1
automationService.preview(flowId, cron);
Defensive patterns

Strategy: validation

Validate before calling

function cronHasFutureFire(cron, zone) {
  const next = cronParser.nextDateFrom(ZonedDateTime.now(zone), cron);
  return next != null; // false => reject before calling preview
}

Try / catch

try { automationService.preview(flowId, cron); } catch (BusinessException e) { if (e.getCode() == PARAMS_ERROR) { showCronEditorError('schedule has no upcoming fire time'); } else throw e; }

Prevention

When it happens

Trigger: Previewing/saving an automation task whose cron expression, evaluated in the configured zoneId from now, has no occurrence in the future — e.g., an explicit date-only schedule that already passed, or a day-of-month/year combination that never matches.

Common situations: Users typing crons pinned to a past date (e.g., "0 0 0 1 1 ? 2024"); expressions with impossible dates like Feb 30; timezone configuration shifting 'now' past the last occurrence; typos producing a fixed, expired schedule.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/522b9991a92e515d. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowAutomationService.java:167

        requireTask(taskId);
        Page<WorkflowAutomationRun> page = new Page<>(current, pageSize);
        LambdaQueryWrapper<WorkflowAutomationRun> wrapper = Wrappers.lambdaQuery(WorkflowAutomationRun.class)
                .eq(WorkflowAutomationRun::getTaskId, taskId)
                .orderByDesc(WorkflowAutomationRun::getCreateTime);
        Page<WorkflowAutomationRun> result = runMapper.selectPage(page, wrapper);
        return toPageData(result);
    }

    public List<String> preview(String cronExpression, String timezone) {
        ZoneId zoneId = parseZone(timezone);
        CronExpression cron = parseCron(cronExpression);
        ZonedDateTime cursor = ZonedDateTime.now(zoneId);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
        java.util.ArrayList<String> result = new java.util.ArrayList<>();
        for (int i = 0; i < 5; i++) {
            ZonedDateTime next = cron.next(cursor);
            if (next == null) {
                throw new BusinessException(ResponseEnum.PARAMS_ERROR, "cron has no future fire time");
            }
            result.add(next.format(formatter));
            cursor = next;
        }
        return result;
    }

    public WorkflowAutomationRun runNow(Long id) {
        WorkflowAutomationTask task = requireTask(id);
        return runTask(task, TRIGGER_MANUAL, new Date());
    }

    public void scanAndRunDueTasks() {
        Date now = new Date();
        List<WorkflowAutomationTask> tasks = list(Wrappers.lambdaQuery(WorkflowAutomationTask.class)
                .eq(WorkflowAutomationTask::getDeleted, false)
                .eq(WorkflowAutomationTask::getEnabled, true)
                .le(WorkflowAutomationTask::getNextFireTime, now)

View on GitHub (pinned to 5e758547a8)