twentyhq/twenty · warning · Error

Cron expression is required

Error message

Cron expression is required

What it means

describeCronExpression guards its entry: it throws when `expression` is undefined/null or trims to empty, before any parsing attempt. This is input validation, distinct from the catch-all wrapper at line 114.

Source

Thrown at packages/twenty-front/src/modules/workflow/workflow-trigger/utils/cron-to-human/describeCronExpression.ts:22

import { getDayOfMonthDescription } from './descriptors/getDayOfMonthDescription';
import { getDayOfWeekDescription } from './descriptors/getDayOfWeekDescription';
import { getHoursDescription } from './descriptors/getHoursDescription';
import { getMinutesDescription } from './descriptors/getMinutesDescription';
import { getMonthsDescription } from './descriptors/getMonthsDescription';
import {
  type CronDescriptionOptions,
  DEFAULT_CRON_DESCRIPTION_OPTIONS,
} from './types/cronDescriptionOptions';
import { parseCronExpression } from './utils/parseCronExpression';

export const describeCronExpression = (
  expression: string,
  options: CronDescriptionOptions = DEFAULT_CRON_DESCRIPTION_OPTIONS,
  localeCatalog?: Locale,
): string => {
  if (!isDefined(expression) || expression.trim() === '') {
    throw new Error('Cron expression is required');
  }

  try {
    const parts = parseCronExpression(expression);
    const mergedOptions = { ...DEFAULT_CRON_DESCRIPTION_OPTIONS, ...options };

    const descriptions: string[] = [];

    // Smart priority: Use hours description when we have specific hours,
    // otherwise use minutes description for patterns like */5
    const hoursDescription = getHoursDescription(
      parts.hours,
      parts.minutes,
      mergedOptions,
    );
    const minutesDescription = getMinutesDescription(
      parts.minutes,
      mergedOptions,

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Check the value is a non-empty string before calling (early-return in the UI).
  2. Provide a sensible default cron expression (e.g., '0 * * * *') for new workflow triggers.
  3. Guard the call site: if (!expression) return '';

Example fix

// before: const desc = describeCronExpression(schedule ?? '');
// after:  const desc = schedule ? describeCronExpression(schedule) : '';
Defensive patterns

Strategy: validation

Validate before calling

const safeDescribeCron = (expr: string | undefined | null): string =>
  expr && expr.trim() ? describeCronExpression(expr) : '';

Type guard

const isNonEmptyCronString = (v: unknown): v is string =>
  typeof v === 'string' && v.trim().length > 0;

Prevention

When it happens

Trigger: Calling describeCronExpression('') , describeCronExpression(undefined as any), or with a whitespace-only string. UI rendering the cron human description before a schedule value has been set.

Common situations: Workflow trigger schedule UI rendered with an empty default. Programmatic call paths that pass through before the user picks a frequency.

Related errors


AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12). Data as JSON: /api/errors/f130ca8fc85a5b6b. Report an issue: GitHub.