chenhg5/cc-connect · error

either prompt or exec is required

Error message

either prompt or exec is required

What it means

validateTimerJob requires every TimerJob to carry work: either a Prompt (text sent to the agent session) or an Exec (shell command). A job with neither would fire and do nothing, so AddJob rejects it.

Source

Thrown at core/timer.go:68

		return 0
	}
	return time.Duration(*j.TimeoutMins) * time.Minute
}

// UsesNewSessionPerRun reports whether the timer should use a new engine session.
func (j *TimerJob) UsesNewSessionPerRun() bool {
	return NormalizeCronSessionMode(j.SessionMode) == "new_per_run"
}

func validateTimerJob(j *TimerJob) error {
	if strings.TrimSpace(j.SessionKey) == "" {
		return fmt.Errorf("session_key is required")
	}
	if j.ScheduledAt.IsZero() {
		return fmt.Errorf("scheduled_at is required")
	}
	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")
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Set Prompt on the job if it should send text to the agent session.
  2. Set Exec instead if the job should run a shell command.
  3. For interactive builders, reject/reprompt the user earlier if neither was supplied.
  4. Add a caller-side check `if j.Prompt == "" && j.Exec == ""` before AddJob to fail with context.

Example fix

// before
job := &core.TimerJob{SessionKey: k, ScheduledAt: when} // nothing to do
sched.AddJob(job)
// after
job := &core.TimerJob{SessionKey: k, ScheduledAt: when, Prompt: "summarize open PRs"}
sched.AddJob(job)
Defensive patterns

Strategy: validation

Validate before calling

if job.Prompt == "" && job.Exec == "" { return errors.New("timer job needs prompt or exec") }

Prevention

When it happens

Trigger: AddJob with a TimerJob where both Prompt=="" and Exec=="" — typically a struct built from a config entry containing neither the prompt nor exec key, or code that clears Prompt based on a flag but never sets Exec.

Common situations: TOML/JSON timer definitions where the user typed the schedule but forgot the prompt; conditional builders that set Exec only in one branch; copying an existing job and blanking fields.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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