temporalio/temporal · error

error validating ContinueAsNewWorkflowExecutionCommand TaskQ

Error message

error validating ContinueAsNewWorkflowExecutionCommand TaskQueue: %w. WorkflowType=%s TaskQueue=%s

What it means

ValidateContinueAsNewWorkflowExecutionAttributes rejects a ContinueAsNew command whose TaskQueue fails NormalizeAndValidateUserDefined (empty, too long, or invalid characters) against the max ID length limit. The command then fails the workflow task with this wrapped message.

Source

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

	// Inherit workflow type from previous execution if not provided on command
	if attributes.WorkflowType == nil || attributes.WorkflowType.GetName() == "" {
		attributes.WorkflowType = &commonpb.WorkflowType{Name: executionInfo.WorkflowTypeName}
	}

	wfType := attributes.WorkflowType.GetName()
	if len(wfType) > v.maxIDLengthLimit {
		return failedCause, serviceerror.NewInvalidArgumentf("WorkflowType on ContinueAsNewWorkflowExecutionCommand exceeds length limit. WorkflowType=%s Length=%d Limit=%d", wfType, len(wfType), v.maxIDLengthLimit)
	}

	// Inherit task queue from previous 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, executionInfo.TaskQueue, executionInfo.TaskQueue, v.maxIDLengthLimit); err != nil {
		return failedCause, fmt.Errorf("error validating ContinueAsNewWorkflowExecutionCommand TaskQueue: %w. WorkflowType=%s TaskQueue=%s", err, wfType, attributes.TaskQueue)
	}

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

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

	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
	}

View on GitHub (pinned to bde624efd1)

Solutions

  1. Trim whitespace and sanitize the task queue name before ContinueAsNew
  2. Check length against the server max ID limit (default 255)
  3. Omit the TaskQueue option to inherit the current task queue
  4. Reuse executionInfo task queue rather than a freshly constructed one

Example fix

// before
workflow.NewContinueAsNewError(ctx, fn, opts.TaskQueue(strings.TrimSpace(userInput)))
// after
if queue := strings.TrimSpace(userInput); queue != "" && len(queue) <= 255 {
    workflow.NewContinueAsNewError(ctx, fn, opts.TaskQueue(queue))
}
Defensive patterns

Strategy: validation

Validate before calling

func validTaskQueue(tq string, max int) bool { tq = strings.TrimSpace(tq); return len(tq) > 0 && len(tq) <= max }

Type guard

func asTaskQueueOption(name string) (workflow.ContinueAsNewOption, bool) { if name == "" { return nil, false }; return opts.TaskQueue(name), true }

Try / catch

deferred recovery: recover from panic in workflow and inspect temporal.ApplicationError details for task queue validation failures

Prevention

When it happens

Trigger: A workflow calling workflow.NewContinueAsNewError with a TaskQueue option containing an invalid/empty/oversized queue name, detected in history's command validation.

Common situations: Dynamically computed task queue names with whitespace or illegal characters; exceeding 255-char ID limits; forgetting to set TaskQueue when the original queue was system-generated.

Related errors


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