temporalio/temporal · error
invalid WorkflowRetryPolicy on StartChildWorkflowExecutionCo
Error message
invalid WorkflowRetryPolicy on StartChildWorkflowExecutionCommand: %w. WorkflowId=%s WorkflowType=%s Namespace=%s
What it means
ValidateStartChildExecutionAttributes rejects a StartChildWorkflowExecution command whose RetryPolicy fails validation in the child namespace context. The workflow task fails with this wrapped message identifying WorkflowId/Type/Namespace.
Source
Thrown at service/history/api/command_attr_validator.go:522
if len(wfType) > v.maxIDLengthLimit {
return failedCause, serviceerror.NewInvalidArgumentf("WorkflowType on StartChildWorkflowExecutionCommand exceeds length limit. WorkflowId=%s WorkflowType=%s Length=%d Limit=%d Namespace=%s", wfID, wfType, len(wfType), v.maxIDLengthLimit, ns)
}
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,View on GitHub (pinned to bde624efd1)
Solutions
- Fix RetryPolicy values: InitialInterval > 0, coefficient >= 1, MaximumInterval >= InitialInterval
- Use SDK default retry policy helpers
- Validate the policy before starting the child workflow
Example fix
// before
opts := workflow.ChildWorkflowOptions{RetryPolicy: &workflowsvc.RetryPolicy{BackoffCoefficient: 0.5}}
// after
opts := workflow.ChildWorkflowOptions{RetryPolicy: &workflowsvc.RetryPolicy{InitialInterval: durationpb.New(time.Second), BackoffCoefficient: 2}} Defensive patterns
Strategy: validation
Validate before calling
func validChildRetry(p *workflowsvc.RetryPolicy) bool { return p == nil || (p.GetInitialInterval().AsDuration() > 0 && p.GetBackoffCoefficient() >= 1) } Type guard
func retryPolicyFromOptions(o workflow.ChildWorkflowOptions) *workflowsvc.RetryPolicy { return o.RetryPolicy } Try / catch
child workflow start fails as workflow task failure; check child workflow history for the StartChildWorkflowExecutionCommandFailed event
Prevention
- Sanity-check all intervals before setting RetryPolicy
- Use retry.BuildDefaultOutbox-style SDK defaults where available
- Test policies in integration tests
When it happens
Trigger: ChildWorkflowOptions with an invalid RetryPolicy (non-positive InitialInterval, BackoffCoefficient < 1, MaximumInterval < InitialInterval) when the parent issues the StartChildWorkflowExecution command.
Common situations: Unit mistakes in retry intervals (ms/s); serializing a zero-value struct as if it were a full policy; cross-namespace children inheriting policies that don't validate in the target namespace.
Related errors
- invalid WorkflowRetryPolicy on ContinueAsNewWorkflowExecutio
- invalid CronSchedule on StartChildWorkflowExecutionCommand:
- invalid SearchAttributes on StartChildWorkflowCommand: %w. W
- error validating ContinueAsNewWorkflowExecutionCommand TaskQ
- invalid SearchAttributes on ContinueAsNewWorkflowExecutionCo
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/621d358a37c74205.
Report an issue: GitHub.