temporalio/temporal · error

invalid CronSchedule on StartChildWorkflowExecutionCommand:

Error message

invalid CronSchedule on StartChildWorkflowExecutionCommand: %w. WorkflowId=%s WorkflowType=%s Namespace=%s

What it means

The StartChildWorkflowExecution command's CronSchedule fails backoff.ValidateSchedule (not a valid cron expression per the server's parser). The workflow task fails with this wrapped message.

Source

Thrown at service/history/api/command_attr_validator.go:526

	if err := timestamp.ValidateAndCapProtoDuration(attributes.GetWorkflowExecutionTimeout()); err != nil {
		return failedCause, serviceerror.NewInvalidArgumentf("Invalid WorkflowExecutionTimeout on StartChildWorkflowExecutionCommand: %v. WorkflowId=%s WorkflowType=%s Namespace=%s", err, wfID, wfType, ns)
	}

	if err := timestamp.ValidateAndCapProtoDuration(attributes.GetWorkflowRunTimeout()); err != nil {
		return failedCause, serviceerror.NewInvalidArgumentf("Invalid WorkflowRunTimeout on StartChildWorkflowExecutionCommand: %v. WorkflowId=%s WorkflowType=%s Namespace=%s", err, wfID, wfType, ns)
	}

	if err := timestamp.ValidateAndCapProtoDuration(attributes.GetWorkflowTaskTimeout()); err != nil {
		return failedCause, serviceerror.NewInvalidArgumentf("Invalid WorkflowTaskTimeout on StartChildWorkflowExecutionCommand: %v. WorkflowId=%s WorkflowType=%s Namespace=%s", err, wfID, wfType, ns)
	}

	if err := v.validateWorkflowRetryPolicy(namespace.Name(attributes.GetNamespace()), attributes.RetryPolicy); err != nil {
		return failedCause, fmt.Errorf("invalid WorkflowRetryPolicy on StartChildWorkflowExecutionCommand: %w. WorkflowId=%s WorkflowType=%s Namespace=%s", err, wfID, wfType, ns)
	}

	if err := backoff.ValidateSchedule(attributes.GetCronSchedule()); err != nil {
		return failedCause, fmt.Errorf("invalid CronSchedule on StartChildWorkflowExecutionCommand: %w. WorkflowId=%s WorkflowType=%s Namespace=%s", err, wfID, wfType, ns)
	}

	if err := v.searchAttributesValidator.Validate(attributes.GetSearchAttributes(), targetNamespace.String()); err != nil {
		return enumspb.WORKFLOW_TASK_FAILED_CAUSE_BAD_SEARCH_ATTRIBUTES, fmt.Errorf("invalid SearchAttributes on StartChildWorkflowCommand: %w. WorkflowId=%s WorkflowType=%s Namespace=%s", err, wfID, wfType, ns)
	}

	if err := priorities.Validate(attributes.Priority); err != nil {
		return failedCause, err
	}

	// Inherit taskqueue from parent workflow execution if not provided on command
	if attributes.TaskQueue == nil {
		attributes.TaskQueue = &taskqueuepb.TaskQueue{
			Kind: enumspb.TASK_QUEUE_KIND_NORMAL,
		}
	}
	if err := tqid.NormalizeAndValidateUserDefined(
		attributes.TaskQueue, parentInfo.TaskQueue, parentInfo.TaskQueue, v.maxIDLengthLimit); err != nil {

View on GitHub (pinned to bde624efd1)

Solutions

  1. Test the cron string with a standard 5-field cron parser before use
  2. Verify field count and ranges (minute 0-59, hour 0-23, etc.)
  3. Use @-macros (@daily, @hourly) where supported

Example fix

// before
opts := workflow.ChildWorkflowOptions{CronSchedule: "0 25 * *"}
// after
opts := workflow.ChildWorkflowOptions{CronSchedule: "0 25 * * *"}
Defensive patterns

Strategy: validation

Validate before calling

if err := backoff.ValidateSchedule(opts.CronSchedule); err != nil { return fmt.Errorf("invalid cron: %w", err) }

Type guard

func hasCron(o workflow.ChildWorkflowOptions) (string, bool) { return o.CronSchedule, o.CronSchedule != "" }

Try / catch

inspect StartChildWorkflowExecutionCommandFailed event failure details in parent workflow history; correct the cron string and restart

Prevention

When it happens

Trigger: ChildWorkflowOptions.CronSchedule set to a malformed cron string (wrong field count, invalid characters, out-of-range values) when starting a child workflow.

Common situations: Using 6-field Quartz-style cron with seconds where the server expects 5-field (or vice versa); typos like */0; config-provided cron strings never validated client-side.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/4b113e23957db92b. Report an issue: GitHub.