Skip to Content

v0.1.76 — 25 May 2026

Bug Fix — Cron jobs triggered from extensions now execute the current code

Who is affected: Anyone whose runtime extensions call services.cron.trigger() or context.services.cron.trigger() to fire a cron job.

What was wrong

Cron jobs triggered from an extension ran with the code that was compiled when the server last started. Edits made to the cron job after startup were ignored by extension-triggered runs, even hours later. Running the same job via the UI “Run Now” button or the MCP run_now action always used the current code.

Root cause

Next.js splits server-side code into multiple webpack chunks at build time. The CronManager module was evaluated separately in the startup chunk (which initialises the scheduler) and in the API-route chunk (which handles saves and manual triggers). This produced two independent CronManager instances, each with its own compiled-handler cache.

When a cron job was saved, the save API called reloadJob() on the API-route instance — updating that cache — while the startup instance (used by the scheduler and by services.cron.trigger()) retained the old compiled code from startup.

The RuntimeExtensionManager (for extensions) and the event emitter already used a globalThis singleton pattern specifically to prevent this. CronManager was missing the same treatment.

What changed

CronManager is now stored on globalThis, matching the pattern already used by RuntimeExtensionManager. All execution paths — scheduled ticks, UI/MCP triggers, and extension-triggered runs — share the same instance, so saving a cron job always updates the cache used by every caller.

Before / After

Trigger pathBefore this fixAfter this fix
Scheduled tick✅ Current code (startup cache)✅ Current code
UI “Run Now” / MCP run_now✅ Current code (API cache)✅ Current code
services.cron.trigger() from extension❌ Startup-time code (stale)✅ Current code

Improvement — Timeout field now accepts any value above the minimum

Affected pages: Extension detail, Cron job detail.

The Timeout (ms) input previously enforced a hard upper limit in the UI (30 s for extensions, 5 min for cron jobs). This cap has been removed. The field now accepts any value above its minimum — 100 ms for extensions, 1 000 ms for cron — so operators can configure whatever execution window their workloads require.

Last updated on