{"record":{"id":"89f8b58e01cbe643","repo":"temporalio/temporal","slug":"invalid-workflowretrypolicy-on-continueasnewworkfl","errorCode":null,"errorMessage":"invalid WorkflowRetryPolicy on ContinueAsNewWorkflowExecutionCommand: %w. WorkflowType=%s TaskQueue=%s","messagePattern":"invalid WorkflowRetryPolicy on ContinueAsNewWorkflowExecutionCommand: %w\\. WorkflowType=(.+?) TaskQueue=(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/history/api/command_attr_validator.go","lineNumber":448,"sourceCode":"\n\tif err := timestamp.ValidateAndCapProtoDuration(attributes.GetBackoffStartInterval()); err != nil {\n\t\treturn failedCause, serviceerror.NewInvalidArgumentf(\"Invalid BackoffStartInterval on ContinueAsNewWorkflowExecutionCommand: %v. WorkflowType=%s TaskQueue=%s\", err, wfType, attributes.TaskQueue)\n\t}\n\n\tif attributes.GetWorkflowRunTimeout().AsDuration() == 0 {\n\t\tattributes.WorkflowRunTimeout = executionInfo.WorkflowRunTimeout\n\t}\n\n\tif attributes.GetWorkflowTaskTimeout().AsDuration() == 0 {\n\t\tattributes.WorkflowTaskTimeout = executionInfo.DefaultWorkflowTaskTimeout\n\t}\n\n\tattributes.WorkflowRunTimeout = durationpb.New(overrideWorkflowRunTimeout(attributes.GetWorkflowRunTimeout().AsDuration(), executionInfo.GetWorkflowExecutionTimeout().AsDuration()))\n\n\tattributes.WorkflowTaskTimeout = durationpb.New(overrideWorkflowTaskTimeout(namespaceName, attributes.GetWorkflowTaskTimeout().AsDuration(), attributes.GetWorkflowRunTimeout().AsDuration(), v.config.DefaultWorkflowTaskTimeout))\n\n\tif err := v.validateWorkflowRetryPolicy(namespaceName, attributes.RetryPolicy); err != nil {\n\t\treturn failedCause, fmt.Errorf(\"invalid WorkflowRetryPolicy on ContinueAsNewWorkflowExecutionCommand: %w. WorkflowType=%s TaskQueue=%s\", err, wfType, attributes.TaskQueue)\n\t}\n\n\tif err := v.searchAttributesValidator.Validate(attributes.GetSearchAttributes(), namespaceName.String()); err != nil {\n\t\treturn enumspb.WORKFLOW_TASK_FAILED_CAUSE_BAD_SEARCH_ATTRIBUTES, fmt.Errorf(\"invalid SearchAttributes on ContinueAsNewWorkflowExecutionCommand: %w. WorkflowType=%s TaskQueue=%s\", err, wfType, attributes.TaskQueue)\n\t}\n\n\treturn enumspb.WORKFLOW_TASK_FAILED_CAUSE_UNSPECIFIED, nil\n}\n\nfunc (v *CommandAttrValidator) ValidateStartChildExecutionAttributes(\n\tnamespaceID namespace.ID,\n\ttargetNamespaceID namespace.ID,\n\ttargetNamespace namespace.Name,\n\tattributes *commandpb.StartChildWorkflowExecutionCommandAttributes,\n\tparentInfo *persistencespb.WorkflowExecutionInfo,\n\tdefaultWorkflowTaskTimeoutFn dynamicconfig.DurationPropertyFnWithNamespaceFilter,\n) (enumspb.WorkflowTaskFailedCause, error) {\n","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/api/command_attr_validator.go#L430-L466","documentation":"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.","triggerScenarios":"Workflow invokes ContinueAsNew with a RetryPolicy option containing invalid values (zero/negative InitialInterval, coefficient < 1, invalid MaximumAttempts/Expiration combination).","commonSituations":"Copying retry policy from config with unit mistakes (ms vs s); setting MaximumInterval smaller than InitialInterval; coefficient defaults missing on hand-built policies.","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"],"exampleFix":"// before\npolicy := &workflowsvc.RetryPolicy{MaximumAttempts: 3, InitialInterval: durationpb.New(0)}\n// after\npolicy := &workflowsvc.RetryPolicy{MaximumAttempts: 3, InitialInterval: durationpb.New(time.Second), BackoffCoefficient: 2}","handlingStrategy":"validation","validationCode":"func validRetryPolicy(p *workflowsvc.RetryPolicy) bool { return p.GetInitialInterval().AsDuration() > 0 && p.GetBackoffCoefficient() >= 1 && (p.GetMaximumInterval() == nil || p.GetMaximumInterval().AsDuration() >= p.GetInitialInterval().AsDuration()) }","typeGuard":"func hasRetryPolicy(a *workflowsvc.ContinueAsNewWorkflowExecutionCommandAttributes) *workflowsvc.RetryPolicy { return a.GetRetryPolicy() }","tryCatchPattern":"err := validator.ValidateContinueAsNewWorkflowExecutionAttributes(...); if err != nil { return err } — callers see workflow task failure; inspect workflow history event failure details","preventionTips":["Use SDK default retry policy helpers","Check config-derived intervals for unit errors","Verify MaximumInterval >= InitialInterval"],"tags":["retrypolicy","workflow","continueasnew","validation","history"],"backgroundTag":"invalid-retry-policy","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}