agent loop detected: bouncing between "compatibility_date too old" and "too new"
Breaks an agent out of bouncing compatibility_date between "too old" and "too new" errors. Use when an autonomous loop keeps changing the date and each change produces the opposite complaint. Trigger: consecutive passes show the date moving older then newer (or vice versa) with alternating "too old" / "too new" style failures.
TL;DR
Stop moving the date and pin it to a known-good value: the most recent Cloudflare compatibility date on or before today that your dependencies support. "Too old" means some API or flag you use needs a newer runtime; "too new" means a dependency breaks on newer behavior. The fix is one deliberate date plus the code or dependency change that the chosen date requires, not date ping-pong.
agent loop detected: bouncing between "compatibility_date too old" and "too new"- Freeze the date. Write down the current value and the exact error it produces, then do not change the date again until step 4.
Expected: a stable baseline: one date, one error, in the run log.
- Read the "too old" error literally. It names something that requires a newer runtime: a compatibility flag, a node: API, a runtime method. Note the minimum date it implies.
Expected: a lower bound, e.g. "needs compatibility_date of 2024-09-01 or later for this flag".
- Read the "too new" error literally. It names something that broke under newer behavior: a dependency relying on old semantics, a removed legacy behavior. Note the maximum date it tolerates.
Expected: an upper bound, e.g. "library X breaks on dates after 2025-06-01".
- Pick a date inside the window [lower bound, upper bound]. If the window is empty (lower bound later than upper bound), the date cannot fix this: upgrade or replace the dependency that imposes the upper bound, or polyfill the API that imposes the lower bound, then re-derive the window.
Expected: one chosen date with a written reason, plus the accompanying dependency/code change if the window was empty.
- Set the date once, apply the accompanying change, and test. From here the date is frozen; only code and dependencies move.
Expected: the alternating errors stop because the date no longer moves. Remaining failures are single-sided and debuggable.
Use this when
- The date moves older then newer across passes with opposite errors each time.
- The agent's only "fix" is editing compatibility_date.
- Errors mention dates, flags, or runtime behavior versions.
Not for this skill when
- The date changed once as part of a deliberate upgrade with code changes alongside. That is normal.
- The error is "compatibility date is invalid" (malformed date). That is a format fix, not a window problem.
- Only one side has ever been tried. Try moving the date once, with diagnosis, before calling it a loop.
Variant phrasings
- agent oscillating compatibility_date
- compatibility date too old too new loop
- workers runtime version ping pong
- autonomous agent bouncing runtime date
Why it happens
compatibility_date selects a runtime behavior snapshot, and dependencies have opinions about which snapshot they work on. The agent treats the date as a free variable to satisfy whichever error is newest, so satisfying error A (move newer) creates error B (move older) creates error A. The date is the wrong variable: the conflict is between two dependencies' requirements, and it resolves by changing a dependency or adding a code shim, with the date pinned to a value both sides tolerate.
Edge cases
- "Too new" sometimes comes from wrangler itself being older than the date (an old wrangler does not know future dates). Check wrangler --version before blaming dependencies; upgrading wrangler can widen the window.
- Lock the date in every env block, not just the top level. An [env.production] override with a different date reintroduces the bounce on deploys even after local is stable.
- Document the chosen date and why in a comment next to it. The next agent (or human) that "fixes" a behavior by moving the date will restart the loop without that note.
- If no window exists and neither side can change, the escape hatch is usually the nodejs_compat flag or a targeted polyfill, which decouples the dependency from the date entirely.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_CkOmj7NkpqkE4MzaneASYQ