chenhg5/cc-connect · error

reschedule failed

Error message

reschedule failed: %w

What it means

After successfully persisting the field change, UpdateJob reschedules the cron entry when the change affects firing (cron_expr or enabled). If cs.scheduleJob returns an error, the store already has the new value but the in-memory timer could not be updated, so the error is wrapped with "reschedule failed".

Solutions

  1. Validate the cron expression with the same parser scheduleJob uses before calling UpdateJob
  2. Retry with a valid cron_expr value; the stored state is already updated so only the timer needs fixing
  3. Check scheduler logs/next-fire time; restarting the daemon will rebuild timers from the store

Example fix

// before
cs.UpdateJob(id, "cron_expr", "99 * * * *") // invalid expression
// after
if parser.Valid("99 * * * *") == false { return errors.New("invalid cron expression") }
cs.UpdateJob(id, "cron_expr", "0 * * * *")
Defensive patterns

Strategy: validation

Validate before calling

if field == "cron_expr" {
    if _, err := cron.ParseStandard(expr); err != nil { return err }
}

Try / catch

if err := cs.UpdateJob(id, "cron_expr", expr); err != nil {
    var wrapped error
    if errors.Unwrap(err) != nil { wrapped = err }
    slog.Error("cron reschedule failed; store updated but timer not rebuilt", "id", id, "err", err)
    _ = wrapped
}

Prevention

When it happens

Trigger: Updating cron_expr to an invalid expression that scheduleJob cannot parse, or enabling a job whose schedule cannot be computed — any scheduleJob failure after a successful store.Update.

Common situations: User edits a job to a malformed cron expression via handleCronEdit; the new expression was accepted by the store but rejected by the scheduler.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/3ebec5dc45abe7ea. Report an issue: GitHub.

Appendix: source

Thrown at core/cron.go:606

		cs.mu.Lock()
		if entryID, ok := cs.entries[id]; ok {
			cs.cron.Remove(entryID)
			delete(cs.entries, id)
		}
		cs.mu.Unlock()
	}

	// Update the field
	if !cs.store.Update(id, field, value) {
		return fmt.Errorf("failed to update field %q (may be read-only or invalid type)", field)
	}

	// Reschedule if needed
	if needsReschedule {
		updatedJob := cs.store.Get(id)
		if updatedJob != nil && updatedJob.Enabled {
			if err := cs.scheduleJob(updatedJob); err != nil {
				return fmt.Errorf("reschedule failed: %w", err)
			}
		}
	}

	return nil
}

func (cs *CronScheduler) Store() *CronStore {
	return cs.store
}

// NextRun returns the next scheduled run time for a job, or zero if not scheduled.
func (cs *CronScheduler) NextRun(jobID string) time.Time {
	cs.mu.RLock()
	entryID, ok := cs.entries[jobID]
	cs.mu.RUnlock()
	if !ok {
		return time.Time{}

View on GitHub (pinned to 4000b2338a)