chenhg5/cc-connect · error

invalid mode %q

Error message

invalid mode %q

What it means

validateTimerJob checks the optional TimerJob.Mode (permission mode for the agent run) against a fixed allowlist: "default", "bypassPermissions", "acceptEdits", "plan", "auto", "dontAsk". Any other non-empty string fails validation in AddJob.

Source

Thrown at core/timer.go:81

	}
	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")
	}
	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 {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Set Mode to one of: "default", "bypassPermissions", "acceptEdits", "plan", "auto", "dontAsk".
  2. Omit Mode entirely (empty string) to inherit the session's default permission mode.
  3. Map legacy names in your config loader (e.g. "yolo" -> "bypassPermissions") before constructing the job.
  4. Keep the allowlist in sync if new modes are added upstream and re-validate stored jobs.

Example fix

// before
job := &core.TimerJob{SessionKey: k, ScheduledAt: when, Prompt: p, Mode: "yolo"}
sched.AddJob(job)
// after
job := &core.TimerJob{SessionKey: k, ScheduledAt: when, Prompt: p, Mode: "bypassPermissions"}
sched.AddJob(job)
Defensive patterns

Strategy: validation

Validate before calling

var validModes = map[string]bool{"default":true,"bypassPermissions":true,"acceptEdits":true,"plan":true,"auto":true,"dontAsk":true}
if job.Mode != "" && !validModes[job.Mode] { return fmt.Errorf("bad mode %q", job.Mode) }

Prevention

When it happens

Trigger: AddJob with TimerJob.Mode set to an unknown permission mode string, e.g. "yolo", "acceptAll", "bypass", or a value valid in a different tool but not in this allowlist.

Common situations: Copying a permission-mode name from another agent CLI; typos in config.toml; older configs using names that were later renamed into the current set.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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