temporalio/temporal · error

invalid SearchAttributes on StartChildWorkflowCommand: %w. W

Error message

invalid SearchAttributes on StartChildWorkflowCommand: %w. WorkflowId=%s WorkflowType=%s Namespace=%s

What it means

The StartChildWorkflowExecution command's SearchAttributes fail validation against the target namespace. Fails with WORKFLOW_TASK_FAILED_CAUSE_BAD_SEARCH_ATTRIBUTES and a message that notably says 'StartChildWorkflowCommand' (legacy wording).

Source

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

	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 {
		return failedCause, fmt.Errorf("invalid TaskQueue on StartChildWorkflowExecutionCommand: %w. WorkflowId=%s WorkflowType=%s Namespace=%s TaskQueue=%s", err, wfID, wfType, ns, attributes.TaskQueue)
	}

	// workflow execution timeout is left as is

View on GitHub (pinned to bde624efd1)

Solutions

  1. Register the search attributes in the target namespace
  2. Use TypedSearchAttributes typed keys
  3. Confirm key/value type pairing matches namespace schema

Example fix

// before
opts := workflow.ChildWorkflowOptions{TypedSearchAttributes: attrsForParentNamespace}
// after
opts := workflow.ChildWorkflowOptions{TypedSearchAttributes: attributesValidInTargetNamespace}
Defensive patterns

Strategy: validation

Validate before calling

for k, v := range searchAttrs { if !registeredInNamespace(targetNS, k) { return fmt.Errorf("key %s not registered in %s", k, targetNS) } }

Type guard

func asTypedSearchAttributes(o workflow.ChildWorkflowOptions) (temporal.SearchAttributes, bool) { return o.TypedSearchAttributes, !o.TypedSearchAttributes.IsEmpty() }

Try / catch

catch WORKFLOW_TASK_FAILED_CAUSE_BAD_SEARCH_ATTRIBUTES in history event details; register missing keys in the target namespace, then retry the child start

Prevention

When it happens

Trigger: ChildWorkflowOptions carrying invalid search attributes (unregistered keys, wrong types, deprecated SearchAttributes map) evaluated against targetNamespace.

Common situations: Attributes registered in the parent namespace but not the child/target namespace; mixing deprecated SearchAttributes with TypedSearchAttributes; key typos.

Related errors


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