From c3a320c27b03f420aab7d9b888a002a834636a19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Fri, 1 May 2026 07:51:21 +0200 Subject: [PATCH] fix: register all cron jobs in twenty-app-dev image (#20167) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary The `twenty-app-dev` Docker image previously passed `--dev-mode` to `cron:register:all`, which skipped all calendar, messaging, and workflow sync cron jobs (only 4 generic crons were registered). This caused periodic sync to silently stop after the initial import for community members using the dev image as their actual instance. ## What changed - Removed `--dev-mode` flag from `packages/twenty-docker/twenty-app-dev/rootfs/etc/s6-overlay/scripts/register-crons.sh` so the dev image registers all cron jobs (matching production behavior) - Removed the now-unused `--dev-mode` option, `DEV_MODE_COMMANDS` set, and conditional filtering logic from `cron-register-all.command.ts` ## Why this is safe - **No log noise**: cron jobs gracefully no-op when no connected accounts exist — they query for pending channels, find zero, and exit early - **No false banner**: the "reconnect account" banner only shows when a user explicitly connected an account whose OAuth later fails, which is correct behavior. No seed/demo data creates connected accounts, so a fresh dev instance won't see any banner - **Hiding crons just hid the symptom**: silently breaking sync with no user feedback is worse than showing the banner if OAuth is misconfigured ## Context Surfaced by a community member who reported that calendar sync cron jobs never appeared in the queue after restarting the dev image, and only the initial import worked. `--dev-mode` was added in #19138 as an optimization for development but it doesn't match how the dev image is actually used by community members deploying Twenty. ## Test plan - [ ] Build/run the `twenty-app-dev` image - [ ] Confirm worker logs show all cron jobs registering (calendar, messaging, workflow, etc.) - [ ] With no connected accounts: confirm no errors or log noise - [ ] With a connected Google calendar: confirm periodic sync triggers after ~5 minutes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 --- .../etc/s6-overlay/scripts/register-crons.sh | 2 +- .../commands/cron-register-all.command.ts | 37 ++----------------- 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/packages/twenty-docker/twenty-app-dev/rootfs/etc/s6-overlay/scripts/register-crons.sh b/packages/twenty-docker/twenty-app-dev/rootfs/etc/s6-overlay/scripts/register-crons.sh index 89975dede5..86c1940247 100644 --- a/packages/twenty-docker/twenty-app-dev/rootfs/etc/s6-overlay/scripts/register-crons.sh +++ b/packages/twenty-docker/twenty-app-dev/rootfs/etc/s6-overlay/scripts/register-crons.sh @@ -4,6 +4,6 @@ set -e echo "==> START Registering cron jobs" cd /app/packages/twenty-server -yarn command:prod cron:register:all --dev-mode +yarn command:prod cron:register:all echo "==> DONE" diff --git a/packages/twenty-server/src/database/commands/cron-register-all.command.ts b/packages/twenty-server/src/database/commands/cron-register-all.command.ts index 0381719d4d..d50b4e7f8b 100644 --- a/packages/twenty-server/src/database/commands/cron-register-all.command.ts +++ b/packages/twenty-server/src/database/commands/cron-register-all.command.ts @@ -1,6 +1,6 @@ import { Logger } from '@nestjs/common'; -import { Command, CommandRunner, Option } from 'nest-commander'; +import { Command, CommandRunner } from 'nest-commander'; import { MarketplaceCatalogSyncCronCommand } from 'src/engine/core-modules/application/application-marketplace/crons/commands/marketplace-catalog-sync.cron.command'; import { StaleRegistrationCleanupCronCommand } from 'src/engine/core-modules/application/application-oauth/stale-registration-cleanup/commands/stale-registration-cleanup.cron.command'; @@ -68,33 +68,8 @@ export class CronRegisterAllCommand extends CommandRunner { super(); } - private devMode = false; - - @Option({ - flags: '--dev-mode', - description: - 'Only register cron jobs relevant to app development (cron triggers, marketplace sync, version check, stale cleanup)', - required: false, - }) - parseDevMode(): boolean { - this.devMode = true; - - return true; - } - - private static readonly DEV_MODE_COMMANDS = new Set([ - 'CronTrigger', - 'MarketplaceCatalogSync', - 'ApplicationVersionCheck', - 'StaleRegistrationCleanup', - ]); - async run(): Promise { - this.logger.log( - this.devMode - ? 'Registering app-dev cron jobs...' - : 'Registering all background sync cron jobs...', - ); + this.logger.log('Registering all background sync cron jobs...'); const allCommands = [ { @@ -195,18 +170,12 @@ export class CronRegisterAllCommand extends CommandRunner { }, ]; - const commands = this.devMode - ? allCommands.filter(({ name }) => - CronRegisterAllCommand.DEV_MODE_COMMANDS.has(name), - ) - : allCommands; - let successCount = 0; let failureCount = 0; const failures: string[] = []; const successes: string[] = []; - for (const { name, command } of commands) { + for (const { name, command } of allCommands) { try { this.logger.log(`Registering ${name} cron job...`); await command.run();