chenhg5/cc-connect · error

timeout_mins must be >= 0

Error message

timeout_mins must be >= 0

What it means

validateTimerJob rejects a TimerJob whose optional TimeoutMins pointer is non-nil but negative. A negative timeout is nonsensical for job execution; zero (nil or 0) means no timeout, positive values cap the run.

Source

Thrown at core/timer.go:85

	if j.Prompt == "" && j.Exec == "" {
		return fmt.Errorf("either prompt or exec is required")
	}
	if j.Prompt != "" && j.Exec != "" {
		return fmt.Errorf("prompt and exec are mutually exclusive")
	}
	mode := NormalizeCronSessionMode(j.SessionMode)
	if mode != "" && mode != "new_per_run" {
		return fmt.Errorf("invalid session_mode %q (want reuse, new_per_run, or new-per-run)", j.SessionMode)
	}
	if j.Mode != "" {
		switch j.Mode {
		case "default", "bypassPermissions", "acceptEdits", "plan", "auto", "dontAsk":
		default:
			return fmt.Errorf("invalid mode %q", j.Mode)
		}
	}
	if j.TimeoutMins != nil && *j.TimeoutMins < 0 {
		return fmt.Errorf("timeout_mins must be >= 0")
	}
	return nil
}

// TimerStore persists timer jobs to a JSON file.
type TimerStore struct {
	path string
	mu   sync.Mutex
	jobs []*TimerJob
}

func NewTimerStore(dataDir string) (*TimerStore, error) {
	dir := filepath.Join(dataDir, "timers")
	if err := os.MkdirAll(dir, 0o755); err != nil {
		return nil, err
	}
	path := filepath.Join(dir, "jobs.json")
	s := &TimerStore{path: path}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Use 0 for 'no timeout' and nil for 'unset'; never a negative number.
  2. Fix the sentinel: replace *TimeoutMins = -1 with TimeoutMins = nil before AddJob.
  3. Clamp loaded config values: if v < 0 { v = 0 } when parsing timeout_mins.
  4. Check the caller-side computation that produced the negative duration.

Example fix

// before
to := -1
job := &core.TimerJob{SessionKey: k, ScheduledAt: when, Prompt: p, TimeoutMins: &to}
sched.AddJob(job)
// after
job := &core.TimerJob{SessionKey: k, ScheduledAt: when, Prompt: p, TimeoutMins: nil} // nil = unset
sched.AddJob(job)
Defensive patterns

Strategy: validation

Validate before calling

if job.TimeoutMins != nil && *job.TimeoutMins < 0 { return errors.New("timeout_mins must be >= 0") }

Prevention

When it happens

Trigger: AddJob with a TimerJob whose TimeoutMins points to a negative int (e.g. int32/int pointer to -1 used as a 'default' sentinel, or arithmetic that subtracted past zero).

Common situations: Using -1 as a sentinel for 'unset' instead of leaving the pointer nil; config values like timeout_mins = -5; computing a remaining-time budget that underflowed.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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