twentyhq/twenty · error · Error

Invalid cron expression. Expected 4-6 fields, got ${parts.le

Error message

Invalid cron expression. Expected 4-6 fields, got ${parts.length}

What it means

Thrown by parseCronExpression after whitespace normalization and the `/N` -> `*/N` rewrite: the split must yield between 4 and 6 tokens. Fewer than 4 or more than 6 means the input is not a recognizable cron expression.

Source

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

import { CronExpressionParser } from 'cron-parser';
import { isDefined } from 'twenty-shared/utils';
import { normalizeWhitespace } from './normalizeWhitespace';

export const parseCronExpression = (
  expression: string,
): CronExpressionParts => {
  if (!isDefined(expression) || expression.trim() === '') {
    throw new Error('Cron expression is required');
  }

  let normalized = normalizeWhitespace(expression);

  normalized = normalized.replace(/(^|\s)\/(\d+)/g, '$1*/$2');

  const parts = normalized.split(/\s+/);

  if (parts.length < 4 || parts.length > 6) {
    throw new Error(
      `Invalid cron expression. Expected 4-6 fields, got ${parts.length}`,
    );
  }

  try {
    CronExpressionParser.parse(normalized, { tz: 'UTC' });

    // Handle different cron formats that cron-parser accepts
    if (parts.length === 4) {
      // Reduced format: hour day month dayOfWeek (minute defaults to 0)
      return {
        seconds: '0',
        minutes: '0',
        hours: parts[0],
        dayOfMonth: parts[1],
        month: parts[2],
        dayOfWeek: parts[3],
      };

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Count the space-separated fields of the input; pad to 5 with '*' for minute/hour/day/month/dayOfWeek as needed.
  2. For '*/5' style inputs, append the missing fields: '*/5 * * * *'.
  3. Validate token count in the UI before submission and show inline guidance.

Example fix

// before: parseCronExpression('*/5')
// after:  parseCronExpression('*/5 * * * *')
Defensive patterns

Strategy: validation

Validate before calling

const countCronFields = (expr: string): number =>
  expr.replace(/(^|\s)\/(\d+)/g, '$1*/$2').trim().split(/\s+/).filter(Boolean).length;
// guard: const n = countCronFields(expr); if (n < 4 || n > 6) showError(`got ${n} fields`);

Type guard

const hasValidCronFieldCount = (expr: string): boolean => {
  const n = countCronFields(expr);
  return n >= 4 && n <= 6;
};

Try / catch

try { parseCronExpression(expr); } catch (e) {
  if (/Expected 4-6 fields/.test((e as Error).message)) setFieldError('Use 5 fields: minute hour day month dayOfWeek');
}

Prevention

When it happens

Trigger: Input like '*/5' (2 tokens), a full sentence, a cron with extra trailing fields, or stray spaces producing unexpected token counts. The `/N` rewrite only fixes a leading slash, not missing fields.

Common situations: User enters a partial cron ('*/5' instead of '*/5 * * * *'). Copy-paste with line breaks or tabs that normalizeWhitespace collapses oddly. Misconfigured preset that builds the cron string incorrectly.

Related errors


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