argoproj/argo-workflows · error

duplicate synchronization item found

Error message

duplicate synchronization item found

What it means

When a workflow declares its synchronization section, Argo collects all sync items (semaphores and mutexes) and checks for duplicates with reflect.DeepEqual. If two entries in the list are exactly identical — same type, same namespace, name and key — the configuration is rejected as ambiguous, because the workflow would wait on the same lock twice. Note this error is created with errors.New without a code (plain error, not a coded ArgoError).

Source

Thrown at workflow/sync/syncitems.go:30

	mutex     *v1alpha1.Mutex
}

func allSyncItems(sync *v1alpha1.Synchronization) ([]*syncItem, error) {
	var syncItems []*syncItem
	for _, semaphore := range sync.Semaphores {
		syncItems = append(syncItems, &syncItem{semaphore: semaphore})
	}
	for _, mtx := range sync.Mutexes {
		syncItems = append(syncItems, &syncItem{mutex: mtx})
	}
	return syncItems, checkDuplicates(syncItems)
}

func checkDuplicates(items []*syncItem) error {
	for i, item := range items {
		for j := i + 1; j < len(items); j++ {
			if reflect.DeepEqual(*item, *items[j]) {
				return errors.New("duplicate synchronization item found")
			}
		}
	}
	return nil
}

func (i *syncItem) getType() v1alpha1.SynchronizationType {
	switch {
	case i.semaphore != nil:
		return v1alpha1.SynchronizationTypeSemaphore
	case i.mutex != nil:
		return v1alpha1.SynchronizationTypeMutex
	default:
		return v1alpha1.SynchronizationTypeUnknown
	}
}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Deduplicate spec.synchronization: keep one entry per unique semaphore/mutex in the workflow YAML
  2. Search the rendered/templated manifest for repeated blocks (e.g. `grep -n "configMapKeyRef\|mutex"`) and merge them
  3. If duplicates come from overlays/patches, move the synchronization section to the base or use a single source of truth

Example fix

# before
synchronization:
  mutexes:
    - name: my-mutex
    - name: my-mutex
# after
synchronization:
  mutexes:
    - name: my-mutex
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for _, m := range wf.Spec.Synchronization.Mutexes {
    if seen[m.Name] { return fmt.Errorf("duplicate mutex %s", m.Name) }
    seen[m.Name] = true
}

Type guard

func hasDuplicateSyncItems(items []v1alpha1.SemaphoreRef) bool {
    seen := map[string]bool{}
    for _, it := range items {
        k := fmt.Sprintf("%v", it)
        if seen[k] { return true }
        seen[k] = true
    }
    return false
}

Try / catch

if err := wfv1.Validate(wf); err != nil {
    return fmt.Errorf("workflow spec rejected: %w", err) // surfaces duplicate synchronization item found
}

Prevention

When it happens

Trigger: Submitting or linting a workflow whose spec.synchronization contains two identical semaphore or mutex entries (e.g. the same configMapKeyRef name+key listed twice, or the same mutex twice). Raised from checkDuplicates, called by allSyncItems when building the sync items list.

Common situations: Copy-pasting a semaphore block within the same synchronization section; merging YAML fragments (e.g. via Kustomize patches or CI templating) that duplicate an entry; programmatically appending sync items without deduplication.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/45632516d937da7b. Report an issue: GitHub.