← Back to PRs

#13288: fix(cron): normalize string schedule/payload from non-frontier LLMs

by M00N7682 open 2026-02-10 08:55 View on GitHub →
stale
## Summary - Fix `normalizeCronJobInput` to handle `schedule` and `payload` passed as plain strings instead of objects - Non-frontier LLMs (Qwen 3 Coder, Grok) send these as strings, which `isRecord()` silently drops, causing gateway validation to fail with "must have required property" for all four required fields - String schedule is parsed as a cron expression (e.g. `"0 5 * * *"`) or ISO timestamp (e.g. `"2026-03-01T10:00:00Z"`) - String payload is wrapped as `{ kind: "systemEvent", text: payload }` Closes #9283 — thanks @Displayer226 for the detailed report! ## Test plan - [x] String schedule as cron expression: `schedule: "0 5 * * *"` - [x] String schedule as ISO timestamp: `schedule: "2026-03-01T10:00:00Z"` - [x] String payload: `payload: "hello world"` - [x] Combined: string schedule + string payload in a single job object - [x] All 258 existing tests still pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> Updates cron job normalization to accept non-frontier LLM outputs where `schedule` and/or `payload` are sent as plain strings. String schedules are interpreted as either a cron expression (5–6 fields) or an absolute timestamp (ISO/epoch), and string payloads are wrapped into a `systemEvent`. The test suite is extended with cases covering string schedule (cron + ISO), string payload, and combined inputs. Key behavior to double-check before merge: (1) empty/whitespace string `payload` now prevents the existing fallback that constructs payload from top-level `message`/`text`, and (2) unparseable non-empty string `schedule` is currently left as a string in the normalized output (since `next` starts as `{...base}`), which will still fail downstream validation in a less consistent way than prior behavior. <h3>Confidence Score: 4/5</h3> - Mostly safe to merge after addressing two normalization edge cases. - The change is localized to cron normalization and is covered by new tests for the main reported scenarios, but there are two concrete input patterns (empty string payload with message/text present; non-empty but unparseable string schedule) that will now produce invalid normalized output and likely break validation. - src/cron/normalize.ts <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs