temporalio/temporal · error
invalid WorkflowRetryPolicy on ContinueAsNewWorkflowExecutio
Error message
invalid WorkflowRetryPolicy on ContinueAsNewWorkflowExecutionCommand: %w. WorkflowType=%s TaskQueue=%s
What it means
The ContinueAsNew command's WorkflowRetryPolicy fails validateWorkflowRetryPolicy (e.g. invalid backoff coefficients, negative intervals, non-positive maximum attempts format). The workflow task fails with BAD_* cause and this wrapped message.
Source
Thrown at service/history/api/command_attr_validator.go:448
if err := timestamp.ValidateAndCapProtoDuration(attributes.GetBackoffStartInterval()); err != nil {
return failedCause, serviceerror.NewInvalidArgumentf("Invalid BackoffStartInterval on ContinueAsNewWorkflowExecutionCommand: %v. WorkflowType=%s TaskQueue=%s", err, wfType, attributes.TaskQueue)
}
if attributes.GetWorkflowRunTimeout().AsDuration() == 0 {
attributes.WorkflowRunTimeout = executionInfo.WorkflowRunTimeout
}
if attributes.GetWorkflowTaskTimeout().AsDuration() == 0 {
attributes.WorkflowTaskTimeout = executionInfo.DefaultWorkflowTaskTimeout
}
attributes.WorkflowRunTimeout = durationpb.New(overrideWorkflowRunTimeout(attributes.GetWorkflowRunTimeout().AsDuration(), executionInfo.GetWorkflowExecutionTimeout().AsDuration()))
attributes.WorkflowTaskTimeout = durationpb.New(overrideWorkflowTaskTimeout(namespaceName, attributes.GetWorkflowTaskTimeout().AsDuration(), attributes.GetWorkflowRunTimeout().AsDuration(), v.config.DefaultWorkflowTaskTimeout))
if err := v.validateWorkflowRetryPolicy(namespaceName, attributes.RetryPolicy); err != nil {
return failedCause, fmt.Errorf("invalid WorkflowRetryPolicy on ContinueAsNewWorkflowExecutionCommand: %w. WorkflowType=%s TaskQueue=%s", err, wfType, attributes.TaskQueue)
}
if err := v.searchAttributesValidator.Validate(attributes.GetSearchAttributes(), namespaceName.String()); err != nil {
return enumspb.WORKFLOW_TASK_FAILED_CAUSE_BAD_SEARCH_ATTRIBUTES, fmt.Errorf("invalid SearchAttributes on ContinueAsNewWorkflowExecutionCommand: %w. WorkflowType=%s TaskQueue=%s", err, wfType, attributes.TaskQueue)
}
return enumspb.WORKFLOW_TASK_FAILED_CAUSE_UNSPECIFIED, nil
}
func (v *CommandAttrValidator) ValidateStartChildExecutionAttributes(
namespaceID namespace.ID,
targetNamespaceID namespace.ID,
targetNamespace namespace.Name,
attributes *commandpb.StartChildWorkflowExecutionCommandAttributes,
parentInfo *persistencespb.WorkflowExecutionInfo,
defaultWorkflowTaskTimeoutFn dynamicconfig.DurationPropertyFnWithNamespaceFilter,
) (enumspb.WorkflowTaskFailedCause, error) {
View on GitHub (pinned to bde624efd1)
Solutions
- Use SDK RetryPolicy builders / client defaults instead of hand-building the proto
- Validate InitialInterval > 0, BackoffCoefficient >= 1, MaximumInterval >= InitialInterval
- Check numeric fields for zero-values from unpopulated config structs
Example fix
// before
policy := &workflowsvc.RetryPolicy{MaximumAttempts: 3, InitialInterval: durationpb.New(0)}
// after
policy := &workflowsvc.RetryPolicy{MaximumAttempts: 3, InitialInterval: durationpb.New(time.Second), BackoffCoefficient: 2} Defensive patterns
Strategy: validation
Validate before calling
func validRetryPolicy(p *workflowsvc.RetryPolicy) bool { return p.GetInitialInterval().AsDuration() > 0 && p.GetBackoffCoefficient() >= 1 && (p.GetMaximumInterval() == nil || p.GetMaximumInterval().AsDuration() >= p.GetInitialInterval().AsDuration()) } Type guard
func hasRetryPolicy(a *workflowsvc.ContinueAsNewWorkflowExecutionCommandAttributes) *workflowsvc.RetryPolicy { return a.GetRetryPolicy() } Try / catch
err := validator.ValidateContinueAsNewWorkflowExecutionAttributes(...); if err != nil { return err } — callers see workflow task failure; inspect workflow history event failure details Prevention
- Use SDK default retry policy helpers
- Check config-derived intervals for unit errors
- Verify MaximumInterval >= InitialInterval
When it happens
Trigger: Workflow invokes ContinueAsNew with a RetryPolicy option containing invalid values (zero/negative InitialInterval, coefficient < 1, invalid MaximumAttempts/Expiration combination).
Common situations: Copying retry policy from config with unit mistakes (ms vs s); setting MaximumInterval smaller than InitialInterval; coefficient defaults missing on hand-built policies.
Related errors
- error validating ContinueAsNewWorkflowExecutionCommand TaskQ
- invalid SearchAttributes on ContinueAsNewWorkflowExecutionCo
- invalid WorkflowRetryPolicy on StartChildWorkflowExecutionCo
- errInvalidWorkflowExecutionTimeoutSeconds
- errInvalidWorkflowRunTimeoutSeconds
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/89f8b58e01cbe643.
Report an issue: GitHub.