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
- Set Mode to one of: "default", "bypassPermissions", "acceptEdits", "plan", "auto", "dontAsk".
- Omit Mode entirely (empty string) to inherit the session's default permission mode.
- Map legacy names in your config loader (e.g. "yolo" -> "bypassPermissions") before constructing the job.
- 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
- Keep a shared allowlist constant instead of hand-typing mode strings in configs
- Map legacy/foreign permission-mode names to the current set during config load
- Copy mode strings from the reference docs verbatim, respecting case
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
- invalid session_mode %q (want reuse, new_per_run, or new-per
- invalid --platform-type %q, want feishu or lark
- unsupported app_type %q (only claude and codex are supported
- invalid platform type %q (want feishu or lark)
- invalid session_mode %q (want reuse, new_per_run, or new-per
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/d90f2ffa303ccd5b.
Report an issue: GitHub.