chenhg5/cc-connect · error

cron_expr must be a string

Error message

cron_expr must be a string

What it means

UpdateJob's cron_expr branch requires the new value to be a Go string; a non-string value (JSON number, bool, nested object) is rejected with this error before any parsing. This guards the reflection-based setter which only handles strings.

Source

Thrown at core/cron.go:544

		delete(cs.entries, id)
	}
	cs.mu.Unlock()
	return nil
}

// UpdateJob modifies a field of a cron job and reschedules if necessary.
// Returns error if job not found, field is read-only, or value is invalid.
func (cs *CronScheduler) UpdateJob(id string, field string, value any) error {
	job := cs.store.Get(id)
	if job == nil {
		return fmt.Errorf("job %q not found", id)
	}

	// Validate cron expression if updating cron_expr
	if field == "cron_expr" {
		expr, ok := value.(string)
		if !ok {
			return fmt.Errorf("cron_expr must be a string")
		}
		if _, err := cron.ParseStandard(expr); err != nil {
			return fmt.Errorf("invalid cron expression %q: %w", expr, err)
		}
	}

	// Validate mode if updating mode field
	if field == "mode" {
		if v, ok := value.(string); ok && v != "" {
			switch v {
			case "default", "bypassPermissions", "acceptEdits", "plan", "auto", "dontAsk":
			default:
				return fmt.Errorf("invalid mode %q (want default, bypassPermissions, acceptEdits, plan, auto, or dontAsk)", v)
			}
		}
	}

	// Validate session_mode if updating session_mode field

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Pass the cron expression as a plain string: UpdateJob(id, "cron_expr", "0 9 * * *").
  2. If the value comes from JSON, ensure the client sends it quoted, or coerce with fmt.Sprintf only for numeric input.
  3. Coerce any to string at the handler boundary before calling UpdateJob.

Example fix

// before
sched.UpdateJob(id, "cron_expr", 930) // int
// after
sched.UpdateJob(id, "cron_expr", "30 9 * * *")
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := value.(string); !ok { return fmt.Errorf("cron_expr must be a string") }

Type guard

func asString(v any) (string, bool) { s, ok := v.(string); return s, ok }

Prevention

When it happens

Trigger: CronScheduler.UpdateJob(id, "cron_expr", value) where value is not a string, e.g. an unmarshaled JSON number 5 or a []any of cron fields.

Common situations: API clients sending typed JSON values instead of strings; template engines that render numbers without quotes; test code passing non-string literals.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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