twentyhq/twenty · warning · Error

Cron expression is required

Error message

Cron expression is required

What it means

Lower-level guard inside parseCronExpression: thrown when the input is undefined/null or trims to empty, before whitespace normalization and field splitting. This is the parse-layer counterpart to error 67.

Source

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

import { type CronExpressionParts } from '@/workflow/workflow-trigger/utils/cron-to-human/types/cronExpressionParts';
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

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Validate non-empty at the caller before invoking parseCronExpression.
  2. Return early / show empty state when the schedule field is blank.

Example fix

// before: const parts = parseCronExpression(value); // value may be ''
// after:  if (!value?.trim()) throw new Error('cron required');
//         const parts = parseCronExpression(value);
Defensive patterns

Strategy: validation

Validate before calling

const safeParseCron = (expr: string | undefined | null) =>
  expr && expr.trim() ? parseCronExpression(expr) : null;

Type guard

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

Prevention

When it happens

Trigger: Direct or indirect call to parseCronExpression('') or parseCronExpression(undefined as any). describeCronExpression's guard (67) usually catches this first, so a direct hit means parseCronExpression was called on its own.

Common situations: Custom call sites that validate a cron string before describe. Test harness passing empty input.

Related errors


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