chenhg5/cc-connect · error
invalid mode %q (want default, bypassPermissions, acceptEdit
Error message
invalid mode %q (want default, bypassPermissions, acceptEdits, plan, auto, or dontAsk)
What it means
validateCronJob restricts the optional Mode (permission mode) field to a fixed allowlist: default, bypassPermissions, acceptEdits, plan, auto, or dontAsk. Any other non-empty string is rejected at job creation so the scheduler never persists a job with an unsupported permission mode.
Source
Thrown at core/cron.go:107
func validateCronJob(j *CronJob) error {
// SessionKey anchors the cron execution to a platform (ExecuteCronJob
// derives platformName from the prefix before ":"). Without it the job
// is persisted but fails at fire-time with the unhelpful
// `platform "" not found for session ""`. Reject it up front so the
// caller (management API, /cron/add, /cron edit) sees an immediate
// 400 instead of a job that silently never runs.
if strings.TrimSpace(j.SessionKey) == "" {
return fmt.Errorf("session_key is required")
}
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 (want default, bypassPermissions, acceptEdits, plan, auto, or dontAsk)", j.Mode)
}
}
if j.TimeoutMins != nil && *j.TimeoutMins < 0 {
return fmt.Errorf("timeout_mins must be >= 0")
}
return nil
}
// CronStore persists cron jobs to a JSON file.
type CronStore struct {
path string
mu sync.Mutex
jobs []*CronJob
}
func NewCronStore(dataDir string) (*CronStore, error) {
dir := filepath.Join(dataDir, "crons")
if err := os.MkdirAll(dir, 0o755); err != nil {View on GitHub (pinned to 4000b2338a)
Solutions
- Set Mode to one of exactly: "default", "bypassPermissions", "acceptEdits", "plan", "auto", or "dontAsk" — or omit the field for the default.
- Fix casing to match the allowlist exactly (e.g. "bypassPermissions", not "BypassPermissions").
- Replace legacy mode names from older configs with the current allowlist equivalents.
- Constrain the management UI/API client to a fixed enum of the six accepted values.
Example fix
// before
job := core.CronJob{..., Mode: "dangerously-skip-permissions"}
core.AddJob(job) // 400
// after
job := core.CronJob{..., Mode: "bypassPermissions"}
core.AddJob(job) Defensive patterns
Strategy: validation
Validate before calling
var validModes = []string{"default", "bypassPermissions", "acceptEdits", "plan", "auto", "dontAsk"}
func validateMode(m string) error {
for _, v := range validModes {
if m == v { return nil }
}
return fmt.Errorf("invalid mode %q", m)
} Try / catch
if err := validateMode(job.Mode); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := core.AddJob(job); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
} Prevention
- Copy mode strings exactly from the allowlist — casing matters (bypassPermissions, acceptEdits)
- Map legacy mode names (e.g. from older configs) to current ones at load time
- Expose only the six allowed modes in management UIs and API clients
- Omit Mode entirely for default permission behavior instead of guessing a value
When it happens
Trigger: Calling AddJob (or the /cron add / edit endpoints) with Mode set to an unrecognized string such as "safe", "yolo", "normal", "YOLO", or an agent-specific mode not in the allowlist.
Common situations: Users copying mode names from another tool's CLI flags (e.g. "dangerously-skip-permissions"); case mismatches like "DEFAULT" or "AcceptEdits"; older config files carrying modes from previous versions that were renamed; UIs allowing free-text mode entry.
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
- %s must be true or false
- timeout_mins must be an integer
- invalid --platform-type %q, want feishu or lark
- unsupported app_type %q (only claude and codex are supported
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/c395aa42743a60b4.
Report an issue: GitHub.